Directory navigation
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:
- Microservice topic 01-Spring Application
- Microservice topic 02-Spring Web MVC view technology
- Microservice topic 03-REST
- Microservice topic 04-Spring WebFlux principle
- Microservice topic 05-Spring WebFlux application
- Microservices topic 06-Cloud Native Applications
- Microservice topic 07-Spring Cloud configuration management
- Microservice topic 08-Spring Cloud service discovery
- Microservice topic 09-Spring Cloud load balancing
- Microservice topic 10-Spring Cloud service circuit breaker
- Microservice topic 11-Spring Cloud service call
- Microservice topic 12-Spring Cloud Gateway
- Microservice topic 13-Spring Cloud Stream (on)
- Microservice topic 14-Spring Cloud Bus
- Microservice topic 15-Spring Cloud Stream implementation
- Microservice topic 16-Spring Cloud overall review
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.
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.
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.
- 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:
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
- 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.
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
- zookeeper command line
Through the command ls / to view the node, we found that the local localhost:2181 service has been started successfully!
Write core classes
- 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);
}
}
- 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:
We use port 7070 as the service port and check whether the registration is successful on the zookeeper node:
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
Based on the previously written Controller, let's visit:
http://localhost:7070/services
(returns all service names)
http://localhost:7070/service/instances/spring-cloud-service-discovery-client
(Specify an instance and get detailed information)
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