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