Last month, we learned that Eureka 2.X encountered difficulties and stopped development, but in fact, it had little impact on domestic users. On the one hand, most Chinese use Eureka 1.X series; on the other hand, Spring Cloud supports many service discovery software, and Eureka is just one of them. The following is a comparison of service discovery software and features supported by Spring Cloud:

Feature euerka Consul zookeeper etcd
Service health check Can match support Service status, memory, hard disk, etc (weak) long connection, keepalive Connect the heart
Multi-data center support
Kv storage service support support support
consistency raft paxos raft
cap ap ca cp cp
Using interfaces (multilingual capability) HTTP (sidecars) Supports HTTP and DNS The client http/grpc
Watch support Long polling/ most increments is supported Full/Long polling is supported support Support long polling
Their monitoring metrics metrics metrics
security acl /https acl HTTPS support (weak)
Spring cloud integration Have support Have support Have support Have support

Euerka and Consul are the most widely used of the services found. If you are not familiar with the concept of registry and Euerka, you can refer to my previous article: Spring Cloud (ii) : Registry Eureka. This article mainly introduces you to the use of Spring Cloud Consul.

Consul is introduced

Consul is an open source tool from HashiCorp for service discovery and configuration in distributed systems. Consul’s solution is more “one-stop” than other distributed service registration and discovery solutions, with built-in service registration and discovery framework, distributed consistency protocol implementation, health check, Key/Value storage, and multi-data center solution, eliminating the need to rely on other tools (such as ZooKeeper, etc.). It is also simpler to use. Consul is written in the Go language, making it naturally portable (Linux, Windows, and Mac OS X support); The installation package contains only one executable file for easy deployment and works seamlessly with lightweight containers such as Docker.

Consul’s advantages:

  • Use the Raft algorithm to ensure consistency, which is more straightforward than the complex Paxos algorithm. Zookeeper, by comparison, uses Paxos, while EtCD uses Raft.
  • Supports multiple DCS, and uses different ports for listening on Intranet and extranet services. Multi-dc cluster can avoid single point of failure of a single DC, and its deployment needs to consider network latency and fragmentation. Zookeeper and ETCD do not support the MDC function.
  • Supports health check. Etcd does not provide this functionality.
  • Supports HTTP and DNS interfaces. Zookeeper integration is complex, and ETCD supports only HTTP.
  • Etcd provides a web management interface, but does not provide this function.
  • Consul is a rising star in service registration and configuration management.

Features:

  • Service discovery
  • Health check
  • The Key/Value store
  • Multi-data center

Consul role

  • Client: a stateless client that forwards HTTP and DNS interface requests to the server cluster on the LAN.
  • Server: the server saves configuration information. The high availability cluster communicates with local clients on the LAN and with other data centers through the WAN. The recommended number of servers for each data center is 3 or 5.

Consul client and server also support the use of Consul center, further improving its high availability.

Consul working principle:

  • 1. When the Producer starts, it sends a POST request to Consul telling Consul its IP address and Port
  • Consul sends a health check request to the Producer every 10 seconds (by default) after receiving the Producer’s registration, verifying whether the Producer is healthy
  • When a Consumer sends a GET request/API /address to Producer, he gets a temporary table of storage service IP addresses and ports from Consul. GET the IP and Port of the Producer from the table and send the GET request/API /address
  • 4. The temporary table is updated every 10 seconds and only contains producers who have passed health checks

The Spring Cloud Consul project is a service governance implementation for Consul. Consul is a distributed, highly available system that contains multiple components, but as a whole provides tools for service discovery and service configuration for our infrastructure in a microservices architecture.

Consul VS Eureka

Eureka is a service discovery tool. The architecture is primarily client/server, with a set of Eureka servers per data center, usually one per availability area. Typically Eureka’s customers use an embedded SDK to register and discover services. For non-native integration customers, Eureka provides some REST apis that other languages can use to implement operations on the Eureka Server to implement a non-JVM language Eureka Client.

Eureka provides a weakly consistent view of services to provide as much service availability as possible. When a client registers with a server, the server attempts to replicate to another server, but there is no guarantee that the replication will complete. The TTL of service registration is short, requiring heartbeat detection between the client and the server. Unhealthy services or nodes stop heartbeat, causing them to time out and be removed from the registry. Service discovery can be routed to any registered service. Some services may be unavailable due to the interval of heartbeat detection. This simplified model allows for simple cluster administration and high scalability.

Consul offers a number of features, including richer health checks, key-value pair storage, and multi-data centers. Consul requires a suite of services for each data center and agents for each client, similar to using a service like Ribbon. Consul Agent allows most applications to become Consul unknowns, performing service registrations via profiles and discovery via DNS or load balancer Sidecars.

Consul provides a strong consistency guarantee because the server uses the Raft protocol to replicate state. Consul supports a wealth of health checks, including TCP, HTTP, Nagios/Sensu compatible scripts or Eureka based TTL. Client nodes participate in health checks based on the Gossip protocol, which distributes health checks without being a scalability challenge like centralized heartbeat checks. Discovery requests are routed to the elected leader, making them highly consistent by default. Allowing clients to read out of date enables any server to process their requests, enabling linear scalability like Eureka.

Consul’s strong consistency means that it can be used as a lock-in service for leadership elections and cluster coordination. Eureka does not provide similar guarantees, and ZooKeeper is often required to run for services that require coordination or have stronger consistency requirements.

Consul provides a range of capabilities needed to support a service-oriented architecture. This includes service discovery, but also rich health checking, locking, key/value, multi-data center federation, event systems, and ACLs. Tool ecosystems such as Consul and Consul-Template and EnvConsul try to minimize the application changes required for integration to avoid the need for local integration through the SDK. Eureka is part of a larger Netflix OSS suite that anticipates relatively uniform and tightly integrated applications. Thus Eureka solves only a small part of the problem and can be used in conjunction with other tools such as ZooKeeper.

Consul Strong consistency (C) brings:

Service registration is a bit slower than Eureka. Consul’s RAFT protocol requires that more than half of the nodes on Consul have been successfully written to be considered registered. If the Leader fails, the entire Consul becomes unavailable during a re-election. Consistency is guaranteed at the expense of availability.

Eureka guarantees high availability (A) and ultimate consistency:

Registration of services is relatively fast, because there is no need to wait for the registration to go to other nodes, and there is no guarantee that the registration can succeed. When data inconsistency occurs, each Eureka node can provide services normally, even though the registration information on A and B is not identical. This will result in A query for service information if A can’t find it, but B can find it. This ensures availability at the expense of consistency.

Otherwise, Eureka is a servlet program that runs in a servlet container; Consul is written from go.

Consul installation

Consul, unlike Eureka, requires a separate installation. Visit Consul to download the latest version of Consul.

Depending on your system type, Consul supports all major systems, as you can see from the following figure.

Consul__2.1_windows_amd64. zip, which is an executable file in consul.

CD Go to the corresponding directory and run CMD to start Consul

cd D:\Common Files\consul
# start CMD:
consul agent -dev        # -dev indicates development mode, and -server indicates service mode
Copy the code

For convenience, you can create a run.bat script in the same directory to start the script as follows:

consul agent -dev
pause
Copy the code

The startup result is as follows:

After the Consul is successfully started, visit http://localhost:8500 to view the Consul management page

That means our Consul service has been successfully launched.

Consul server

Next we develop Consul’s server, we create a Spring-Cloud-Consul-Producer project

Adding a dependency package

Dependency packages are as follows:

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId>  <scope>test</scope>
	</dependency>
</dependencies>
Copy the code
  • spring-boot-starter-actuatorHealth checks depend on this package.
  • spring-cloud-starter-consul-discoverySpring Cloud Consul support.

The Spring Boot version uses 2.0.3.RELEASE and the latest RELEASE of Spring Cloud is finchley. RELEASE which relies on Spring Boot 2.x.

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> . < version > 2.0.3 RELEASE < / version > < relativePath / > <! -- lookup parent from repository --> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>
Copy the code

The complete POM.xml file you can refer to the sample source code.

The configuration file

The content of the configuration file is as follows

spring.application.name=spring-cloud-consul-producer
server.port=8501
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
The service name to register with Consul
spring.cloud.consul.discovery.serviceName=service-producer
Copy the code

Consul’s address and port number are localhost:8500 by default. Otherwise, you can configure them yourself. Spring. Cloud. Consul. Discovery. ServiceName refers to the service name registered to the consul, the late client will launch a service call according to the name.

Start the class

@SpringBootApplication
@EnableDiscoveryClient
public class ConsulProducerApplication {

	public static void main(String[] args) { SpringApplication.run(ConsulProducerApplication.class, args); }}Copy the code

The @enableDiscoveryClient annotation is added to support service discovery.

To provide services

We’re creating a Controller, and the tweet provides the hello service.

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello(a) {
        return "helle consul"; }}Copy the code

To simulate registration balancing load copy the preceding project rename it spring-Cloud-consul-producer-2, change the corresponding port to 8502, change the hello method return value to “Helle Consul Two”, and start the two projects one by one.

At this time, we visit the address: http://localhost:8500 in the browser again, it shows as follows:

We find that there are many service-producer services on the page. After clicking into the page, there are two service providers:

Then the service provider is ready.

The Consul consumer end

We create a Spring-Cloud-Consul-consumer project with the SAME POM file as the example above.

The configuration file

The content of the configuration file is as follows

Spring. The application. The name = spring - the cloud - consul - consumer server port = 8503 spring. Cloud. Consul. Host = 127.0.0.1 spring.cloud.consul.port=8500Settings do not need to be registered in Consul
spring.cloud.consul.discovery.register=false
Copy the code

Clients can register with Consul or not. You can choose to do so based on your business. You only need to obtain service information from Consul’s interface when using the service.

Start the class

@SpringBootApplication
public class ConsulConsumerApplication {

	public static void main(String[] args) { SpringApplication.run(ConsulConsumerApplication.class, args); }}Copy the code

test

Let’s create a ServiceController, to try if to get Consul in service.

@RestController
public class ServiceController {

    @Autowired
    private LoadBalancerClient loadBalancer;
    @Autowired
    private DiscoveryClient discoveryClient;

   /**
     * 获取所有服务
     */
    @RequestMapping("/services")
    public Object services(a) {
        return discoveryClient.getInstances("service-producer");
    }

    /** * Select a service from all services (polling) */
    @RequestMapping("/discover")
    public Object discover(a) {
        return loadBalancer.choose("service-producer").getUri().toString(); }}Copy the code

There are two methods in the Controller: one is to get information about all services named service-producer and return them to the page; the other is to randomly get one service named service-producer and return it to the page.

After adding the ServiceController we start the project, access to the address: http://localhost:8503/services, return:

[{"serviceId":"service-producer"."host":"windows10.microdone.cn"."port": 8501,"secure":false."metadata": {"secure":"false"},"uri":"http://windows10.microdone.cn:8501"."scheme":null},{"serviceId":"service-producer"."host":"windows10.microdone.cn"."port": 8502,"secure":false."metadata": {"secure":"false"},"uri":"http://windows10.microdone.cn:8502"."scheme":null}]
Copy the code

We found that the two servers with ports 8501 and 8502 that we just created exist.

Multiple access address: http://localhost:8503/discover, pages can alternate returns the following information:

http://windows10.microdone.cn:8501
http://windows10.microdone.cn:8502
...
Copy the code

Note Services 8501 and 8501 appear alternately to achieve load balancing for obtaining server addresses.

Most of the time we want to use load balancing to get the service provided by the server, so we use the second method to simulate calling the hello method provided by the server.

Create CallHelloController:

@RestController
public class CallHelloController {

    @Autowired
    private LoadBalancerClient loadBalancer;

    @RequestMapping("/call")
    public String call(a) {
        ServiceInstance serviceInstance = loadBalancer.choose("service-producer");
        System.out.println("Service Address:" + serviceInstance.getUri());
        System.out.println("Service Name:" + serviceInstance.getServiceId());

        String callServiceResult = new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello", String.class);
        System.out.println(callServiceResult);
        returncallServiceResult; }}Copy the code

Use RestTemplate to make remote calls. After adding, restart the Spring-Cloud-Consul-Consumer project. In the browser to access the address: http://localhost:8503/call, in turn to return the result as follows:

helle consul
helle consul two
...
Copy the code

We have successfully invoked the Consul service and implemented the load balancing function on the Consul server. Consul’s service is easy to discover and powerful.

Example code – Github

Example code – code cloud