[SpringCloud] Service Governance: Spring Cloud Eureka

Spring Cloud Eureka is a part of the Spring Cloud Netlix microservice suite. It is a secondary package based on NetfixEureka and is mainly responsible for completing the service governance function         in the microservice architecture . Spring Cloud adds Spring Boot-style automatic configuration to Eureka, and we can easily integrate the microservice application built by SpringBoot with the Eureka service governance system by simply introducing dependencies and annotation configurations.

When it comes to service governance here, let's take a look at what service governance is.

Service Governance

Service governance can be said to be the most core and basic module in the microservice architecture. It is mainly used to realize the automatic registration and discovery         of each microservice instance . Why do we need the service governance module so much in the microservice architecture? Is there anything bad about the microservice system without it?

        When we first started building a microservice system, there may not be many services. We can complete the service call by doing some static configuration. For example, there are two services A and B. When service A needs to call service B to complete a business operation, in order to achieve high availability of service B, no matter whether server load balancing or client load balancing is used, service B needs to be maintained manually. A list of specific instances of . However, with the development of business, the system functions become more and more complex , and the corresponding microservice applications are also increasing , and our static configuration will become more and more difficult to maintain. And in the face of continuous development of business, our cluster size, service location, service naming, etc. may change. If it is still maintained manually, errors or naming conflicts will easily occur. At the same time, the maintenance of such static content will consume a lot of manpower .

        In order to solve the problem of service instance maintenance in the microservice architecture, a large number of service governance frameworks and products have been produced. The implementation of these frameworks and products revolves around the service registration and service discovery mechanism to complete the automatic management of microservice application instances. .

  • Service registration: In the service governance framework, a registration center is usually built . Each service unit registers the services it provides with the registration center , and informs the registration center of some additional information such as the host and port number , version number , and communication protocol . The registration center Organize the list of services by service name. For example, we have two processes that provide service A running at 192.168.0.100:8000 and 192.168.0.101:8000 respectively, and three processes that provide service B run at 192.168.0.100:9000 and 192.168.0.101:9000 respectively , 192.168.0.102:9000. When these processes are started and register their own services with the registration center, the registration center will maintain a list of services similar to the following. In addition, the service registration center also needs to monitor whether the services in the list are available in a heartbeat manner. If they are not available, they need to be removed from the service list to achieve the effect of troubleshooting services .

  • Service discovery:   Due to the operation under the service governance framework, inter-service calls are no longer realized by specifying a specific instance address, but by initiating a request call to the service name . Therefore, when the service caller calls the service provider interface, he does not know the specific location of the service instance. Therefore, the caller needs to consult the service registry and obtain a list of all service instances to access specific service instances. For example, if the existing service C wants to call service A, service C needs to initiate a consulting service request to the registration center, and the service registration center will return the location list of service A to service C. As in the case of service A in the above example, C will Obtained two available locations 192.168.0.100:8000 and 192.168.0.101:8000 of service A. When service C wants to initiate a call, it takes a location from the list with a certain polling strategy to make a service call , which is the client load balancing that we will introduce later . Here we just enumerate a simple service governance logic to facilitate the understanding of the basic operating ideas of the service governance framework. For factors such as performance, the actual framework will not adopt the method of obtaining services from the service registry every time, and different application scenarios will have some different implementation strategies in mechanisms such as caching and service elimination.

Netflix Eureka
        Spring Cloud Eureka uses Netflix Eureka to realize service registration and discovery. It includes both server-side components and client-side components. Both the server-side and the client-side are written in Java, so Eureka is mainly suitable for implementation through Java. distributed systems, or systems built with JVM-compatible languages. However, since the service governance mechanism of the Eureka server provides a complete RESTful API, it also supports incorporating microservice applications built in non-Java languages ​​into Eureka's service governance system. It's just that when using other language platforms, you need to implement Eureka's client program yourself. Fortunately, there are already some client implementation frameworks for the Eureka registry on several popular development platforms, such as Steeltoe on the .NET platform and eureka-js-client on Node.js.

        The Eureka server is also called the service registry . Like other service registries, it supports high availability configuration. It relies on strong consistency to provide good availability of service instances and can cope with a variety of different failure scenarios. If Eureka is deployed in cluster mode, when a fragment in the cluster fails , Eureka will switch to self-protection mode . It allows discovery and registration of services to continue to be provided during a shard failure, and when the failed shard comes back up, the other shards in the cluster will sync their state back up again. Taking the practice on AWS as an example, Netflix recommends running a Eureka server in each available region to form a cluster. Service registries in different availability zones replicate their state to each other asynchronously, meaning that each instance has a slightly different state about all services at any given point in time.

        Eureka client , mainly handles service registration and discovery . The client service is embedded in the code of the client application through annotations and parameter configuration . When the application is running, the Eureka client registers the services provided by itself with the registry and periodically sends heartbeats to renew its service lease . At the same time, it can also query the currently registered service information from the server and cache them locally and refresh the service status periodically.

        Let's simply build some examples to learn how to use Eureka to build a registry and perform registration and discovery services.

First create a basic Spring Boot project, and introduce the necessary dependencies in pom.xml, the code is as follows:

     <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        Start a service registry through the @EnableEurekaServer annotation to provide dialogue to other applications. This step is very simple, just add this annotation to a normal SpringBoot application to enable this feature.

        However, by default, the service registry will also register itself as a client, so we need to disable its client registration behavior, we only need to add the corresponding configuration in application.properties.

eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://$ {eureka.instance.hostname} :${server.port}/eureka/
  • eureka.client.register-with-eureka: Since the application is a registration center, it is set to false, which means that the registration center does not point to itself.
  • eureka.client.fetch-registry: Since the registry is responsible for maintaining service instances, it does not need to retrieve services, so it is also set to false.

        After completing the above configuration, start the application and visit http://localhost:1111/, we can see the following figure, where Instances currently registered with Eureka is empty, indicating that the registration center has not registered any services. http://localhost:1111/

Here is a description of each function: 

High availability registration center

        In a distributed environment such as the microservice architecture, we need to fully consider the failure situation, so in the production environment, each component must be deployed with high availability. This is true for microservices and the service registry. But so far, we have been using a single-node service registry, which is obviously not suitable in a production environment. We need to build a highly available service registry to enhance the availability of the system.

        The design of Eureka Server considers high availability from the very beginning. In Eureka's service governance design, all nodes are service providers and service consumers , and the service registry is no exception. Do you still remember that in the single-node configuration, we set the following two parameters so that the service registry does not register itself: We need to build a highly available service registry to enhance the availability of the system.

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

        The high availability of Eureka Server is actually to register itself as a service with other service registries , so that a group of service registries registered with each other can be formed to realize the mutual synchronization of service lists and achieve high availability.

        

Service discovery and consumption

        Through the above content introduction and practice, we have built the core component of the microservice architecture - the service registry (including single-node mode and high-availability mode). At the same time, the Spring Boot entry program implemented in the previous chapter has also been modified. Through simple configuration, the program is registered on the Eureka registration center and becomes a service under the service governance system, named hello-service. Now that we have a service registration center and a service provider, let’s try to build one Service consumers, it mainly accomplishes two goals, discovering services and consuming services. Among them, the task of service discovery is completed by Eureka's client , and the task of service consumption is completed by Ribbon . Ribbon is a client-side load balancer based on HTTP and TCP. It can poll access through the ribbonServerList server list configured in the client to achieve load balancing.

        The example design is as follows:

Deploy the Eureka Server server

rely:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

Boot class:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer.class, args);
    }
}

application.yaml configuration file

server:
  port: 8761
eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false
  server:
    waitTimeInMsWhenSyncEmpty: 0

Deploy the Eureka Client client:

rely:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

Boot class:

@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientProviderServer {
        public static void main(String[] args) {
        new SpringApplicationBuilder(EurekaClientProviderServer.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    }
}

application.yaml configuration file:

server:
  port: 8081
eureka:
  client:
    serviceUrl:
      defaultZone: http://127.0.0.1:8761/eureka/
spring:
  application:
    name: eureka-client-provider

 Detailed explanation of Eureka

        Above, through a simple example of service registration and discovery, we constructed three core roles in the Eureka service governance system: service registry , service provider , and service consumer . At present, we already know how to build a service registry (including single-node and high-availability deployments), and how to use Eureka's annotations and configurations to incorporate Spring Boot applications into Eureka's service governance system to become service providers or service consumers By. At the same time, there are some simple contacts for the service consumption of client load balancing. However, in practice, our system structure is often much more complex than the above examples. If we only rely on the previously built service governance content, in most cases it is impossible to fully and directly meet the needs of the business system. We also need to base on actual conditions. Do some configuration, tweaking and scaling. So we should understand Eureka's infrastructure, the communication mechanism between nodes, and some advanced configurations.

infrastructure

  • Service registration center: The server provided by Eureka provides the functions of service registration and discovery, which is what we said above

eureka-server

  • Service provider: The application that provides the service can be a SpringBoot application or an application that follows the Eureka communication mechanism on other technology platforms. It registers the services it provides with Eureka for discovery by other applications, which is the HELLO-SERVICE above.
  • Service consumer: The consumer application obtains the service list from the service registry, so that consumers can know where to call the services they need. Ribbon is generally used to realize service consumption, and there is also Fegin's consumption method.

In fact, in many cases, the client is both a service provider and a service consumer.

Service Governance Mechanism:

        Let's take a closer look at some communication behaviors of various elements in the Eureka infrastructure to understand how the service governance system based on Eureka works. The following figure is an example, in which there are several important elements:

  • "Service Registry-1" and "Service Registry-2", they register with each other to form a high-availability cluster.
  • The "service provider" starts two instances, one is registered to the "service registry-1", and the other is registered to the "service registry-2".
  • There are also two "service consumers", both of which point to only one registration center.

According to the above structure, you can learn more about some important communication behaviors involved in each element, from service registration to service invocation.

service provider

service registration

        When the "service provider" starts, it will register itself with Eureka Server by sending a REST request, and at the same time bring some metadata information of its own service. After receiving the REST request, Eureka Server stores the metadata information in a two-layer structure Map, in which the key of the first layer is the service name, and the key of the second layer is the instance name of the specific service.

        When registering for the service, you need to confirm it. Whether the eureka.client.register-with-eureka-true parameter is correct, the value is true by default. If set to false will not start the registration operation.

service synchronization

        As shown in the architecture diagram, the two service providers here are registered to two different service registration centers respectively, that is to say, their information is maintained by the two service registration centers respectively. At this time, since the service registries are registered with each other as services, when the service provider sends a registration request to a service registry, it will forward the request to other registries connected in the cluster, thereby realizing service synchronization. Through service synchronization, the service information of two service providers can be obtained through any one of the two service registration centers.

Service Renewal

        After registering the service, the service provider will maintain a heartbeat to continuously tell Eureka Server: "I'm still alive" to prevent Eureka Server's "elimination task" from excluding the service instance from the service list. We call it This operation is service renewal (Renew).
        There are two important attributes about service renewal, which we can pay attention to and adjust as needed:

 The eureka.instance.lease-renewal-interval-in-seconds parameter is used to define the invocation interval of the service renewal task, and the default is 30 seconds. The eureka.instance.lease-expiration-duration-in-seconds parameter is used to define the service expiration time, and the default is 90 seconds.

service consumer

get service

        At this point, a service has been registered in the service registry, and the service has two instances. When we start the service consumer, it will send a REST request to the service registry to get the list of services registered above. For performance considerations, Eureka Server will maintain a read-only service list to return to the client, and the cache list will be updated every 30 seconds.

        Obtaining services is the basis of service consumers, so you must ensure that the eureka.client.fetch-registry=true parameter is not modified to false, and the value defaults to true. If you want to modify the update time of the cache list, you can modify it through the eureka.client. registry-fetch-interval-seconds=30 parameter. The default value of this parameter is 30, and the unit is seconds.

service call

        After obtaining the service list, the service consumer can obtain the name of the instance that provides the service and the metadata information of the instance through the service name. Because of the detailed information of these service instances, the client can decide which instance to call according to its own needs. In the Ribbon, the polling method will be used by default to call, so as to realize the load balancing of the client.

        For the selection of access instances, Eureka has the concepts of Region and Zone. A Region can contain multiple Zones. Each service client needs to be registered in a Zone, so each client corresponds to a Region and a Zone. When making a service call, priority is given to accessing the service provider in the same Zone, and if not, access to other Zones.

Service offline

        During the operation of the system, it is inevitable to shut down or restart a certain instance of the service. During the shutdown of the service, we naturally do not want the client to continue to call the closed instance. So in the client program, when the service instance performs a normal shutdown operation, it will trigger a REST request for the service to go offline to the Eureka Server, telling the service registry: "I am going offline." After receiving the request, the server sets the service status as DOWN and propagates the offline event.

Service Registry

failure rejection

        Sometimes, our service instance does not necessarily go offline normally. It may be due to memory overflow, network failure and other reasons that the service cannot work normally, but the service registration center has not received the "service offline" request. In order to remove these instances that cannot provide services from the service list, Eureka Server will create a timed task when it starts, and by default it will time out the current list (90 seconds by default) at regular intervals (by default 90 seconds) without continuing Contracted services are excluded.

self protection

        When we debug Eureka-based programs locally, we basically encounter such a problem. In the information
panel of the service registry center, a red warning message similar to the following appears:

         In fact, this warning triggers the self-protection mechanism of Eureka Server. We have introduced before that after the service is registered to Eureka Server, it will maintain a heartbeat connection and tell Eureka Server that it is still alive. During the operation of Eureka Server, it will count whether the proportion of heartbeat failures is lower than 85% within 15 minutes. If it is lower than the situation (it is easy to meet during stand-alone debugging, the actual production environment is usually due to network instability. result), EurckaServer will protect the current instance registration information, so that these instances will not expire, and protect these registration information as much as possible. However, if there is a problem with the instance during this protection period, the client can easily get the service instance that does not exist, and the call will fail. Therefore, the client must have a fault-tolerant mechanism, such as using request retry , circuit breakers and other mechanisms.

        Since local debugging can easily trigger the protection mechanism of the registration center, this will make the service instance maintained by the registration center less accurate. Therefore, when we develop locally, we can use the eureka.server.enable-self-preservation=false parameter to turn off the protection mechanism to ensure that the registry can correctly remove unavailable instances.
 

Guess you like

Origin blog.csdn.net/weixin_43918614/article/details/124489884