1.What is Spring Cloud Consul?
Spring Cloud ConsulIt is a pair provided by Spring CloudHashiCorp Consulsupport. It is a service mesh-based tool for enabling service registration, discovery, configuration management, and health checks. Main functions include:
- Service registration and discovery: Through Consul's service registration function, Spring Cloud Consul can realize dynamic registration and discovery of microservices, simplifying communication between services.
- Distributed configuration management: Provides management of distributed configuration through Consul's Key/Value storage mechanism.
- Health check: Supports health checks for service instances to ensure that only healthy instances are available for call from other services.
- Election and distributed lock: Supports distributed locking and leadership elections through Consul's conversation mechanism.
Spring Cloud Consul's election mechanism
Spring Cloud Consul's election mechanism is based onConsul session (Session)andKey/Value StoreImplement distributed leadership elections.
How it works:
-
Session creation:
- The service instance creates a session to Consul, which is a temporary, instance-bound object.
- The session comes with TTL (Survival Time), which requires regular renewal and remains active.
-
Get Lock:
- By setting the value of a Key to the current session ID, the service attempts to acquire the lock of that Key.
- Consul uses CAS (Compare and Swap) operations to ensure that only one service instance can successfully acquire the lock.
-
Locked successfully:
- A service instance that successfully acquires the lock is considered a leader.
- Other instances will periodically attempt to acquire the lock, but can only wait for the current lock to be released or timed out.
-
Lock release or invalid:
- If the leader instance fails to renew the session in time (such as a downtime or a network outage), Consul releases the lock associated with the session, and other instances can compete to become new leaders.
2. Environment construction
run Consul Agent
docker run -d --name=dev-consul -p 8500:8500 consul
web ui
http://localhost:8500
3. Code Engineering
Experimental objectives
- Use the session mechanism and key-value store provided by Consul to implement itDistributed leadership elections。
- pass
@InboundChannelAdapter
and@ServiceActivator
Realize periodic inspection of leadership identity and perform leadership tasks.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="/POM/4.0.0" xmlns:xsi="http:///2001/XMLSchema-instance" xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0."> <parent> <artifactId>springcloud-demo</artifactId> <groupId></groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>LeaderElection</artifactId> <properties> <>17</> <>17</> </properties> <dependencies> <dependency> <groupId></groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId></groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId></groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- Spring Cloud Starter Consul Discovery --> <dependency> <groupId></groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <dependency> <groupId></groupId> <artifactId>spring-integration-core</artifactId> </dependency> </dependencies> </project>
package ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; @Configuration public class LeaderElectionConfig { private static final String LEADER_KEY = "service/leader"; private static final String CONSUL_URL = "http://localhost:8500"; private String sessionId; @Bean @InboundChannelAdapter(value = "leaderChannel", poller = @Poller(fixedDelay = "5000")) public MessageSource<String> leaderMessageSource() { return () -> { // Implement logic to check if this instance is the leader boolean isLeader = checkLeadership(); return (isLeader ? "I am the leader" : "I am not the leader").build(); }; } @Bean @ServiceActivator(inputChannel = "leaderChannel") public MessageHandler leaderMessageHandler() { return new MessageHandler() { @Override public void handleMessage(Message<?> message) throws MessagingException { (()); // Implement logic to perform leader-specific tasks } }; } private final RestTemplate restTemplate = new RestTemplate(); public LeaderElectionConfig() { = createSession(); } private String createSession() { String url = CONSUL_URL + "/v1/session/create"; HttpHeaders headers = new HttpHeaders(); HttpEntity<String> entity = new HttpEntity<>("{\"Name\": \"leader-election-session\"}", headers); //ResponseEntity<String> response = (url, entity, ); // PUT ResponseEntity<String> response = (url, , entity, ); // Extract session ID from response return ().split("\"")[3]; // This is a simple way to extract the session ID } public boolean checkLeadership() { String url = CONSUL_URL + "/v1/kv/" + LEADER_KEY + "?acquire=" + sessionId; HttpHeaders headers = new HttpHeaders(); HttpEntity<String> entity = new HttpEntity<>(headers); ResponseEntity<Boolean> response = (url, , entity, ); return (()); } public void releaseLeadership() { String url = CONSUL_URL + "/v1/kv/" + LEADER_KEY + "?release=" + sessionId; HttpHeaders headers = new HttpHeaders(); HttpEntity<String> entity = new HttpEntity<>(headers); ResponseEntity<Boolean> response = (url, , entity, ); if ((())) { ("Released leadership successfully"); } else { ("Failed to release leadership"); } } @PreDestroy public void onExit() { releaseLeadership(); } }
Code explanation
-
initialization:
- Passed at startup
createSession()
Register a session with Consul.
- Passed at startup
-
Periodic tasks:
- Pass every 5 seconds
checkLeadership()
Check the leadership identity. - If you are a leader, perform specific tasks (such as printing logs, executing business logic).
- Pass every 5 seconds
-
Free up resources:
- When the application is closed,
releaseLeadership()
Release the lock.
- When the application is closed,
package ; import ; import ; import ; import ; @SpringBootApplication @EnableDiscoveryClient @EnableIntegration public class LeaderElectionApplication { public static void main(String[] args) { (, args); } }
Configuration File
node1
=8081 =true =true =leader-election-example =localhost =8500 -id=${}:${.instance_id:${}}
node2
=8082 =true =true =leader-election-example =localhost =8500 -id=${}:${.instance_id:${}}
The above are just some key codes.
4. Test
Start node1
java -jar --=node1
Start node2 node
java -jar --=node2
Observe the logs through the console, only one of them can be selected as the host
The above is the detailed content of the code project for Spring Cloud Consul to implement the election mechanism. For more information about the election mechanism of Spring Cloud Consul, please pay attention to my other related articles!