Write up front: this is a microservices topic document that covers the components commonly used in microservices. If you have any questions, you can find the answers in the overall document
The registry
Knowledge index
- What is a registry
- The cap theorem
- Registry comparison
- The service registry
- The service call
What is a registry
When microservices call each other, they need to know the specific address of the called service and whether it is healthy (whether the server is responding), which requires that the registry must have these two capabilities: 1. Ability to allow services to register. 2. Ability to monitor services. If there is only one registry, when it can not provide services for various reasons, our system can not run properly, so the registry is required to have the ability to cluster, and the data between clusters must ensure consistency. Otherwise, when the registry fails to move the host due to the master node, it may get the wrong service list during service invocation due to data inconsistency between the master and slave nodes. So it must also have highly available, consistent clustering capabilities.
2 Registries supported by Spring Cloud and comparison
2.1 cap theorem
CAP principle, also known as CAP theorem, refers to Consistency, Availability and Partition tolerance in a distributed system. The CAP principle is that, at best, these three elements can achieve two, not all at once.
Consistency: Whether all data backups have the same value at the same time. (Equivalent to all nodes accessing the same latest copy of data)
Availability: Whether the cluster can respond to read/write requests from clients after a node in the cluster fails. (High availability for data updates)
In practical terms, partitioning is equivalent to a time-limit requirement for communication. If the system cannot achieve data consistency within the time limit, it means that A partitioning situation has occurred and that it must choose between C and A for the current operation.
The essence of the CAP principle is either AP, CP, or AC, but there is no CAP. If no copy of the data in a distributed system, the system must meet the conditions of strong consistency, because only a data alone, won’t appear inconsistent data, C and P two elements have right now, but if the system network partition condition happened or outage, inevitably lead to some of the data can not access, the availability conditions cannot be met, That is, CP system is obtained in this case, but CAP cannot be both satisfied.
2.2 Registry comparison
Nacos | Eureka | Consul | Zookeeper | |
---|---|---|---|---|
Consistency protocol | CP+AP | AP | CP | CP |
Health check | TCP/HTTP/MYSQL/Client Beat | Client Beat | TCP/HTTP/gRPC/Cmd | Keep Alive |
Load Balancing Policy | Weight/metadata/Selector | Ribbon | Fabio | – |
Avalanche protection | There are | There are | There is no | There is no |
Automatic logout instance | support | support | Does not support | support |
Access protocol | HTTP/DNS | HTTP | HTTP/DNS | TCP |
Listening to the support | support | support | support | support |
Multi-data center | support | support | support | Does not support |
Synchronization across registries | support | Does not support | support | Does not support |
SpringCloud integration | support | support | support | support |
Dubbo integration | support | Does not support | Does not support | support |
K8S integration | support | Does not support | support | Does not support |
The Eureka2.x version has been announced as closed source, Nacos will be introduced in the following Spring CloudAlibaba chapter. In this article, we mainly demonstrate the configuration and use of the registry through Consul.
3 Consul
3.1 introduce Consul
Consul is an open source tool from HashiCorp for service discovery and configuration in distributed systems. Unlike other distributed service registration and discovery solutions, Consul’s solution is more of a “one-stop shop” with a built-in service registration and discovery framework, distributed consistency protocol implementation, health check, Key/Value storage, and multi-data center solution that no longer relies 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.
3.2 Consul Installation (Simulating Linux Operations on a VM)
View all Docker images
docker images
Copy the code
Pull Consul mirror
docker Pull consul # Default pull latest
Copy the code
You can check again that the mirror is already in Consul
Start a Consul container
docker Run -d -p 85:8500 --restart=always --name=consul consul:latest agent-server-bootstrap-uI-node = 1-client ='0.0.0.0' run -d -p 85:8500 --restart=always --name=consul
Copy the code
View the started container
The browser accesses port 8500 on the installation machine
http://ip:8500
Copy the code
If the following page is displayed, the installation is successful
4 Service Registration
Next we develop a simple service registration to the registry.
4.1 Creating a Maven project
Create a new Spring_cloud_demos project and create the Service_Provider module with the following directory structure
4.2 Importing Dependencies
Introduce spring-boot-starter-parent in the parent project
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7. RELEASE</version>
</parent>
Copy the code
The final result is as follows:
Introduce Consul dependencies in the Service_provider
<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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Copy the code
The final result is as follows:
4.3 Configuration File
server:
port: 8001 # service port
spring:
application:
name: service-provider # service name
cloud:
consul:
host: 192.168184.128. Registry address
port: 8500 # registry port
discovery:
service-name: ${spring.application.name} The service name of the service in the registry
Copy the code
4.4 Writing Code
4.4.1 start class
/**
* Copyright (c) 2022 itmentu.com, All rights reserved.
*
* @Author: yang
*/
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceProvicerApplication {
public static void main(String[] args) { SpringApplication.run(ServiceProvicerApplication.class, args); }}Copy the code
Code description:
1:@enableDiscoveryClient Discovers the registry and registers the service with the registry
2:@springBootApplication See the SpringBoot section
Copy the code
4.4.2 Interface programming
/**
* Copyright (c) 2022 itmentu.com, All rights reserved.
*
* @Author: yang
*/
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(a){
return "hello!"; }}Copy the code
4.4.3 Running startup classes
If the console displays the following information, the startup is successful:
On the registry page, the service is registered successfully
5 Service Invocation
5.1 Creating the Service_consumer submodule
5.2 Importing Dependencies
<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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Copy the code
5.3 Configuration File
server:
port: 8001 # service port
spring:
application:
name: service-provider # service name
cloud:
consul:
host: 192.168184.128. Registry address
port: 8500 # registry port
discovery:
service-name: ${spring.application.name} The service name of the service in the registry
register: false Do not register in the registry
Copy the code
Description:
1:Because consumers don't need to register to the registry, so spring. Cloud. Consul. Discovery. Register to false
Copy the code
5.4 Writing Code
5.4.1 start class
/**
* Copyright (c) 2022 itmentu.com, All rights reserved.
*
* @Author: yang
*/
@SpringBootApplication
public class ServiceConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceConsumerApplication.class, args);
}
@Bean
public RestTemplate restTemplate(a){
return newRestTemplate(); }}Copy the code
Code description:
1:Register a RestTemplate into the Spring container for use
Copy the code
5.4.2 Interface programming
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/hello")
public String hello(a){
Obtain the list of service provider instances registered in the registry
List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("service-provider");
//2
ServiceInstance serviceInstance = serviceInstanceList.get(0);
//3, request address based on the instance information stitching
String url = serviceInstance.getUri()+ "/hello";
//4
returnrestTemplate.getForObject(url,String.class); }}Copy the code
Code description:
1:DiscoveryClient is used to obtain the instance of the corresponding service in the registry
2:Serviceinstance.geturi () indicates that the address in the instance includes the IP port
3:RestTemplate is used to make HTTP requests in REST mode
Copy the code
5.4.3 Running the startup class and accessing the interface
Browser access
http://localhost:8002/consumer/hello
Copy the code
You can see
We have successfully accessed the service_provider/Hello interface through consumer and responded to the data