Microservice topic 08-Spring Cloud service discovery

Preface

In the previous chapter, we talked about Spring Cloud configuration management . In this section, continue to share the content of the microservice topic, a total of 16 sections, namely:

The key points of this section are:

  • Zookeeper client: Introduce the basic usage of Spring Cloud Discovery combined with Apache Zookeeper client, including service discovery activation, Eureka client registration configuration and API usage, etc.
  • Zookeeper server: Introduce how to build Apache Zookeeper server as a service registry

Comparison of various registration centers

Point of comparison Eureka Zookeeper Consul
Operation and maintenance familiarity Relatively unfamiliar Familiar with Stranger
Consistency (CAP) AP (eventual consistency) CP (strong consistency) AP (eventual consistency)
Conformance Agreement HTTP scheduled rotation ZAB RAFT
communication method HTTP REST Custom protocol HTTP REST
Update mechanism Peer 2 Peer (between servers) + Scheduler (server and client) ZK Watch Agent monitoring method
Applicable scale 20 K ~ 30 K instance (node) 10K ~ 20K instance (node) <3K instance (node)
Performance issues Simple update mechanism, complex design, frequent GC when large scale Expansion is troublesome and GC is frequent when the scale is large Above 3K nodes, the update list is slow

Why ZK is recommended as the infrastructure of Spring Cloud

The CAP principle, also known as the CAP theorem, refers to the consistency (Consistency), availability (Availability), and partition tolerance (Partition tolerance) in a distributed system. The CAP principle means that these three elements can only achieve two points at the same time, and it is impossible to take care of all three.

Consistency model

Zookeeper guarantees CP: Consistency and Partition tolerance.

Insert picture description here
The above figure describes the situation when the client requests Zookeeper or Eureka as the registry to access, when an application instance of the server hangs, the registry responds differently:

  • For Zk, in order to ensure the CP principle, the number of application instances returned to the client becomes 3-1 = 2.
  • For Eureka, in order to ensure the AP principle, there are still three application instances returned to the client, but the dead instances cannot be accessed.

It is not difficult to imagine that for Eureka, when the server-side application instance hangs, there is a 1/3 probability of the situation in the above picture, and the instance cannot be obtained. In order to avoid this situation, we can usually introduce services The gateway implements a "read-write separation" architecture to solve such problems.

Architecture based on service gateway to achieve separation of read and write

The so-called "read-write separation" refers to:

  • Write: The client directly registers with the Eureka registry for service.
  • Read: The service gateway pulls data from the Eureka registry, so that the client can subscribe to the data indirectly from the service gateway.

Insert picture description here

We know that the Eureka registry is based on a memory- based registration model. The advantage of separating service registration and service discovery is to prevent the two from being parallel. Assuming that the QPS of the Client is 10w or higher, then the Eureka registry is directly exposed to Client, it will definitely cause Eureka to hang up.

In actual business scenarios, generally speaking, the request for service registration is relatively small, only one registration is required, and more is service discovery. The amount of data pulled from Eureka is relatively large, that is, read more and write less.

Based on the above conclusions, we think that since we read more and write less, we can make some articles while reading to realize the distributed high availability of the gateway, add the data pulled by the gateway to the cache, and then persist it to the database, so that the client When reading data, you can access the database indirectly, and at the same time, you can sub-database and sub-table, etc., so that the performance based on the Eureka registry can be greatly expanded.

Relatively familiar with maintenance

Zookeeper ecological environment is better

  • Zookeeper can be used to manage the configuration information of many systems. For example, many distributed systems such as kafka, storm, etc. will use zookeeper to manage some metadata and configuration information. Does the dubbo registry also support zookeeper?

  • Many big data systems such as hadoop, hdfs, and yarn choose to develop HA high availability mechanism based on zookeeper.

  • Zookeeper implements distributed locks is also a relatively common way.

Single configuration center and service registry

The so-called simplification refers to the use of Zookeeper as the registration center, Zookeeper can also be used as the configuration center, if in the traditional configuration of Spring Cloud, use Eureka as the registration center and Git/JDBC as the configuration center.

Spring Cloud Discovery

Through zookeeper's experiment, we can test two effects at the same time:

  • Registration discovery

  • Configuration management

Spring Cloud adds ZK dependency

  • Wrong configuration (high ZK Client version 3.5, low server version 3.4)
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
        </dependency>
    </dependencies>
  • Configure correctly
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zookeeper-all</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.12</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Start ZK

Regarding the use and principle of zk , we have already mentioned in the previous distributed topic , here we will do a review with the Windows version!
Zookeeper official website download: zookeeper official website download

The version I currently use is: 3.5.8.

  1. Modify the default configuration file

Zk reads the zoo.cfg file by default. The one downloaded from the official website is not available. Let's copy a copy here and modify the zoo.cfg
file:
Insert picture description here
we can create a /data folder in the zookeeper root directory to store data.

tickTime=2000
initLimit=10
syncLimit=5
# 这里需要使用 "//" 
dataDir=D://apache-zookeeper-3.5.8-bin//data
clientPort=2181
  1. Start and stop zookeeper

First, double-click zkServer.sh to start the server, then double-click to start zkCli.sh and enter the command line.
Insert picture description here
Stop zookeeper and you can directly kill port 2181:

First check the process number of port 2181:

netstat -aon|findstr “2181”

Then kill directly:

taskkill /pid 10756 /F

Insert picture description here

  1. zookeeper command line

Through the command ls / to view the node, we found that the local localhost:2181 service has been started successfully!
Insert picture description here

Write core classes

  1. Boot class, use @EnableDiscoveryClient as the service discovery client:
@SpringBootApplication
@EnableDiscoveryClient // 尽可能使用 @EnableDiscoveryClient
public class ZkDSClientApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(ZkDSClientApplication.class, args);
    }
}
  1. Write Controller, return all service name, id, host, port number and other information according to DiscoveryClient's api
@RestController
public class ServiceController {
    
    

    @Autowired
    private DiscoveryClient discoveryClient;

    /**
     * 返回所有的服务名称
     *
     * @return
     */
    @GetMapping("/services")
    public List<String> getAllServices() {
    
    
        return discoveryClient.getServices();
    }

    @GetMapping("/service/instances/{serviceName}")
    public List<String> getAllServiceInstances(@PathVariable String serviceName) {
    
    
        return discoveryClient.getInstances(serviceName)
                .stream()
                .map(s ->
                        s.getServiceId() + " - " + s.getHost() + ":" + s.getPort()
                ).collect(Collectors.toList());
    }

}

We noticed that the interface DiscoveryClient comes from org.springframework.cloud.client.discovery.

And the functions are as follows:

public interface DiscoveryClient {
    
    

	/**
	 * A human readable description of the implementation, used in HealthIndicator
	 * @return the description
	 */
	String description();

	/**
	 * Get all ServiceInstances associated with a particular serviceId
	 * @param serviceId the serviceId to query
	 * @return a List of ServiceInstance
	 */
	List<ServiceInstance> getInstances(String serviceId);

	/**
	 * @return all known service ids
	 */
	List<String> getServices();

}

Among them, ServiceInstance, let's see what properties and methods are there?

public interface ServiceInstance {
    
    
	// 实例 id
	String getServiceId();
	//主机地址
	String getHost();
	// 端口号
	int getPort();
	//是否是https请求
	boolean isSecure();
	// 服务的 uri
	URI getUri();
	//与服务实例关联的键值对元数据
	Map<String, String> getMetadata();
	//实例方案
	default String getScheme() {
    
    
		return null;
	}
}

Setup configuration file

spring.application.name = spring-cloud-service-discovery-client

# 服务端口
server.port = 7070

# 管理端口
management.server.port = 7071

# 开放 所有Web 管理 Endpoints
management.endpoints.web.exposure.include = *

Result test

  • First look at the effect of service discovery:

Startup project:
Insert picture description here

We use port 7070 as the service port and check whether the registration is successful on the zookeeper node:
Insert picture description here
we found that the ZK node path (/services/spring-cloud-service-discovery-client/)
can be concluded from this: ZK service discovery node Rules (/services/{spring.application.name}/{serviceId_UUID}/).

  • Next, look at the effect of service registration:

Visit the browser directly: http://localhost:7071/actuator/env

Insert picture description here
Based on the previously written Controller, let's visit:

http://localhost:7070/services
(returns all service names)
Insert picture description here

http://localhost:7070/service/instances/spring-cloud-service-discovery-client
(Specify an instance and get detailed information)
Insert picture description here

postscript

Eureka 2.0 is not open source, Eureka 1.x can still be used

The code address of this section: https://github.com/harrypottry/microservices-project/tree/master/spring-cloud-project/spring-cloud-service-discovery-client

For more architectural knowledge, please pay attention to this series of articles on Java : The Road to Growth of Java Architects

Guess you like

Origin blog.csdn.net/qq_34361283/article/details/106978460