Spring cloud series, service registry Eureka Foundation

Posted by zamzon on Tue, 14 Sep 2021 07:15:16 +0200

1. Registry of microservices

The registry can be said to be the "address book" in the micro service architecture. It records the mapping relationship between services and service addresses. In the distributed architecture, all services are registered here. When a service needs to call other services, it can be called by finding the corresponding service address in the registry.

1.1. Main functions of Registration Center

Service registry is a very important component in microservice architecture and plays a role of coordinator in microservice architecture. The registry generally includes the following functions:

1. Service discovery:

  • Service registration / de registration: save the information of service providers and service callers;
  • Service subscription / unsubscribe: the service caller subscribes to the information of the service provider, preferably with the function of real-time push;
  • Service routing (optional): it has the ability to filter and integrate service providers.

2. Service configuration:

  • Configure subscription: service providers and service callers subscribe to micro service related configurations;
  • Configuration distribution: actively push the configuration to service providers and Wufu callers.

3. Service health test:

  • Check the health of the service provider.

1.2 common registration centers

  • Zookeeper

    zookeeper is a distributed service framework and a sub project of Apache Hadoop. It is mainly used to solve some data management problems often encountered in distributed applications. Such as unified naming service, state synchronization service, cluster management, management of distributed application configuration items, etc.
    Simply put: zookeeper = file system + listening notification mechanism.

  • Eureka

    Eureka is a service registration and discovery component written in Java language and developed based on Restful Api. It is an important component in SpringCloud Netflix.

  • Consul

    Consul is a service component developed by HashiCorp based on Go language, which supports multi data center distributed and highly available service publishing and registration. It adopts Raft algorithm to ensure service consistency and supports health inspection.

  • Nacos

    Nacos is a dynamic service discovery, configuration management and service management platform that is easier to build cloud native applications.
    In short: Nacos is a combination of registry and configuration center.
    It provides an easy-to-use feature set to help us solve the problems of service registration and discovery, service configuration, service management and so on.
    Nacos is also one of the components of Spring Cloud Alibaba, which is responsible for service registration and discovery.

1.3 similarities and differences of common registration centers

Through a table, we can roughly understand the similarities and differences among Eureka, Consul and Zookeeper, and choose what type of service registration and discovery components can be determined according to their own project requirements.

Component namelanguageCAPConsistency algorithmService health checkExternal exposure interface
EurekaJavaAPnothingConfigurable supportHTTP
ConsulGoCPRaftsupportHTTP/DNS
ZookeeperJavaCPPaxossupportclient
NacosJavaAPRaftsupportHTTP

2. Eureka overview

2.1. Eureka's basic knowledge

Eureka is a service discovery framework developed by Netflix. Spring cloud integrates it into its sub project spring cloud Netflix to realize the service discovery function of spring cloud.

The above briefly describes Eureka's infrastructure, which consists of three roles:

  • Eureka

    Provide service registration and discovery

  • Service Provider

    Service provider;
    Register your services with the Eureka registry so that service consumers can find them.

  • Service Consumer

    Service consumers;
    Obtain a list of registered services from the Eureka registry so that you can consume services.

2.2 interaction process and principle of Eureka


The above figure is from Eureka's official architecture diagram, which roughly describes the working process of Eureka cluster. The diagram contains many components, which may be difficult to understand. The following components are introduced:

  • us-east-1c and us-east-1d and us-east-1e

    They belong to the zone. They all belong to the region of us-east-1

  • Apllication Service

    Equivalent to service provider (belonging to Eureka Client)

  • Application Cient

    Equivalent to service consumer (belonging to Eureka Client)

  • Make Remote Call

    It can be simply understood as calling Restful API

As can be seen from the above figure, Eureka contains two components: Eureka Server and Eureka Client. Their functions are as follows:

  • Eureka Client is a Java client (including service providers and consumers) to simplify the interaction with Eureka Server;
  • Eureka Server is the ability to provide service discovery. When each micro service is started, it will register its own information (such as network information) with Eureka Server through Eureka Client, and Eureka Server will store the information of the service;
  • After the microservice is started, it will periodically send heartbeat to Eureka Server (the default cycle is 30 seconds) to renew its online information. If Eureka Server does not receive the heartbeat of a microservice node within a certain period of time, Eureka Server will log off the microservice node (the default detection time is 90 seconds);
  • Each Eureka Server is also an Eureka Client. Multiple Eureka servers synchronize the service registry through replication;
  • Eureka Client caches the information in Eureka Server. Even if all Eureka Server nodes are down, service consumers can still use the information in the cache to find service providers.

To sum up, Eureka improves the flexibility, scalability and availability of the system through heartbeat detection, health check and client caching.

3. Case of building Eureka registry

3.1. Build Eureka Service Center

(1) . create Ebuy Eureka module (for subsequent convenience, you can directly build the SpringBoot project)

  • Inherit Ebuy parent module

(2) Introducing Eureka server dependent coordinates into maven

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

The version number relied on here should be the same as the spring boot starter parent version number of the inherited parent project. If it is different, it should be ensured that the version is not different as much as possible, because the compatibility of higher versions of SpringBoot with Netflix Eureka server is not very perfect.

For the next step, there is another pit here. If you use JDK8, there is no problem in this regard at present; If it is jdk9 or above, there is a problem, that is, there is no configuration on the default class path of jaxb-api in the later versions of jdk9, because jaxb-api is a part of java ee. Since jdk9, Java has introduced the concept of module. You can use the module command - add modules java.xml.bind to introduce JAXB API. Of course, there is a simple and crude method, This is to introduce the following dependencies into the pom file to activate the JAXB API Application interface.

Start Ebuy Eureka with the following error:

java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not present

Resolve the above exception that JAXBContext does not exist:

<!--solve java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not present-->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

(3) Configure application.yml

server:
  port: 9000 #Port number

eureka:
  instance: #eureka instance
    hostname: 127.0.0.1 #server ip address 
  client:
    register-with-eureka: false #Whether to register yourself in the registration center (it regulates all services without registration)
    fetch-registry: false #Whether to obtain the list of services from the registry (all services are regulated by itself, and there is no need to obtain)
    serviceUrl: #Here is the automatic conversion of hump naming method, which can also be written as service URL. Hump naming is recommended
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#The address where Eureka client interacts with Eureka server
serviceUrl: #It can only be written in this way if the context is accepted
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

(4) Configure startup class

package com.ebuy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer //Activate Eureka Server side configuration
public class EbuyEurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EbuyEurekaApplication.class, args);
    }
}

@Enable Eureka Server note: activate Eureka Server side configuration

3.2. Service registration center management background

Start the Ebuy Eureka project startup class, enter the address localhost:9000 in the address bar, and press enter directly to enter the built-in management console of Eureka server. The display effect is as follows. In fact, although the interface in the figure below is different from the visual interface of Dubbo amdin, its function is basically the same, and it is also used for the supervision of the registration center:

4. The client service registers with the Eureka registry

4.1 commodity module service registration

4.1.1. Create Ebuy product module (for subsequent convenience, you can directly build the SpringBoot project)

  • Inherit Ebuy parent module

4.1.2. Introduce Eureka client dependent coordinates into maven

        <!--springcloud Public class dependency-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
        </dependency>

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

        <!--mybatis integration springboot starter-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>

        <!--mysql Connection dependency-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

4.1.3 create pojo, mapper, service and controller layers under com.ebuy.product package

  • Create entity class EasybuyProduct in pojo layer

    package com.ebuy.product.pojo;
    
    import lombok.Data; /*Represents the automatic generation of getter and setter methods*/
    import lombok.ToString;/*Represents an automatically generated toString method*/
    import java.io.Serializable;
    import java.math.BigDecimal;
    
    @Data
    @ToString
    public class EasybuyProduct implements Serializable {
    
        private Long epId;
    
        private String epName;
    
        private String epDescription;
    
        private BigDecimal epPrice;
    
        private Long epStock;
    
        private Long epcId;
    
        private Long epcChildId;
    
        private String epFileName;
    
        private static final long serialVersionUID = 1L;
    }
    
  • The above EasyBuyProduct entity class uses two annotations @ Data and @ ToString, which respectively represent the automatic generation of getter, setter method and toString() method. This method uses the lombok plug-in, which can greatly improve the development efficiency of entity class and save coding space.

  • Step 1: first download the plug-in lombok in the plugins of settings. After installation, pay attention to restart the IDEA to take effect:

  • Step 2: import lombok dependent coordinates in the Ebuy parent parent module. In the future, as long as the Ebuy parent module inherits, the entity class can directly use annotations:

    		<!--lombok Annotation dependency-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.4</version>
                <scope>provided</scope>
            </dependency>
    
  • In this way, the annotations on the above entity classes can be used!

  • Create the EasyBuyProductMapper interface in the mapper layer:

    package com.ebuy.product.mapper;
    
    import com.ebuy.product.pojo.EasybuyProduct;
    
    public interface EasybuyProductMapper {
    
        /**
         * Query commodity information according to commodity id
         * @param epId
         * @return
         */
        EasybuyProduct selectByPrimaryKey(Long epId);
    }
    
  • Create a new com/ebuy/product/mapper directory under the resources directory, and create a new EasyBuyProductMapper.xml mapping file under it:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.ebuy.product.mapper.EasybuyProductMapper" >
      <resultMap id="BaseResultMap" type="com.ebuy.product.pojo.EasybuyProduct" >
        <id column="ep_id" property="epId" jdbcType="DECIMAL" />
        <result column="ep_name" property="epName" jdbcType="VARCHAR" />
        <result column="ep_description" property="epDescription" jdbcType="VARCHAR" />
        <result column="ep_price" property="epPrice" jdbcType="DECIMAL" />
        <result column="ep_stock" property="epStock" jdbcType="DECIMAL" />
        <result column="epc_id" property="epcId" jdbcType="DECIMAL" />
        <result column="epc_child_id" property="epcChildId" jdbcType="DECIMAL" />
        <result column="ep_file_name" property="epFileName" jdbcType="VARCHAR" />
      </resultMap>
    
      <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
        select ep_id, ep_name, ep_description, ep_price, ep_stock, epc_id, epc_child_id, ep_file_name from EASYBUY_PRODUCT
        where ep_id = #{epId,jdbcType=DECIMAL}
      </select>
    
    </mapper>
    
  • Create an EasybuyProductService business logic layer interface in the service layer (consistent with the mapper layer):

    package com.ebuy.product.service;
    
    import com.ebuy.product.pojo.EasybuyProduct;
    
    /**
     * Business logic layer interface
     */
    public interface EasybuyProductService {
    	/**
         * Query commodity information according to commodity id
         * @param epId
         * @return
         */
        EasybuyProduct selectByPrimaryKey(Long epId);
    
    }
    
  • Create an EasyBuyProductServiceImpl implementation class in the service.impl layer:

    package com.ebuy.product.service.impl;
    
    import com.ebuy.product.pojo.EasybuyProduct;
    
    @Service
    @SuppressWarnings("all")
    public class EasybuyProductServiceImpl implements EasybuyProductService {
    
    	/**
         * Call mapper layer interface
         */
        @Autowired
        EasybuyProductMapper easybuyProductMapper;
    
        @Override
        public EasybuyProduct selectByPrimaryKey(Long epId) {
            return easybuyProductMapper.selectByPrimaryKey(epId);
        }
     }
    
  • Create a new ProductContoller in the controller layer:

    package com.ebuy.product.controller;
    
    import com.ebuy.product.pojo.EasybuyProduct;
    import com.ebuy.product.service.EasybuyProductService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    @RequestMapping("/product")
    public class ProductController {
    
    	@Autowired
    	private EasybuyProductService productService;
    
    	@RequestMapping(value = "/{id}",method = RequestMethod.GET)
    	public EasybuyProduct findById(@PathVariable Long id) {
    		EasybuyProduct product = productService.selectByPrimaryKey(id);
     		return product;
    	}
    }
    

4.1.4. Configure application.yml file

server:
  port: 9011 #Port number

spring:
  application:
    name: ebuy-product #Commodity module service name
  datasource:
    username: root #Database user name
    password: root #Database password
    driver-class-name: com.mysql.jdbc.Driver #mysql load driver
    url: jdbc:mysql://localhost:3306/ebuy?useUnicode=true&characterEncoding=utf8

mybatis:
  type-aliases-package: com.ebuy.product.pojo  #mybatis simplifies pojo entity class aliases
  mapper-locations: com/ebuy/product/mapper/*.xml #mapper mapping file path

logging:
  level:
    com.ebuy: DEBUG #log level

eureka:
  client:
    serviceUrl: #Address and port of Ebuy server configured above
      defaultZone: http://127.0.0.1:9000/eureka/
  instance:
    prefer-ip-address: true #Register with ip address (display name in registration center as ip address)

4.1.5 modify the startup class and add service registration annotation

package com.ebuy;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@MapperScan("com.ebuy.product.mapper")
//@Enable Eureka client open Eureka client
//@EnableDiscoveryClient opens the service discovery client
public class EbuyProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(EbuyProductApplication.class, args);
    }
}

Starting with the Spring Cloud Edgware version, @ EnableDiscoveryClient or @ EnableEurekaClient can be omitted. You can register the client micro service on the service discovery component by adding relevant dependencies and configuring them accordingly. However, the annotation @ EnableEurekaServer must be added to the startup class of the above EurekaServer service, indicating that the current service is the Eureka service registry.

4.1.6 start the EbuyProductApplication class to register goods and services with Eureka

4.1.7 access the Restful interface address of the controller layer in the address bar http://localhost:9011/product/816753 , Firefox can parse JSON data, which is exactly what we want:

4.2. Order module service registration (the steps are basically the same as those of the above commodity micro services)

4.2.1. Create Ebuy order module (for subsequent convenience, you can directly build the SpringBoot project)

  • Inherit Ebuy parent module

4.2.2. Introduce Eureka client dependency

		<!--springcloud Dependent public classes-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
        </dependency>
        <!--springcloud Registration Center eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

4.2.3. Also create pojo, mapper, service and controller layers

  • Create a new easybuyorder mapper interface in the mapper layer
  • Create a new EasyBuyOrderService interface in the service layer (consistent with Mapper layer)
  • Create a new EasyBuyOrderServiceImpl entity class under the service.impl package
  • Create a new OrderController class in the controller layer

4.2.4 configure the application.yml file

server:
  port: 9012 #Port number
spring:
  application:
    name: ebuy-order #service name
logging:
  level:
    cn.ebuy: DEBUG

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:9000/eureka/
  instance:
    prefer-ip-address: true   #Register with ip address (display name in registration center as ip address)

4.2.5 modify the startup class and add service registration annotation

package com.ebuy.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
//@Enable Eureka client open Eureka client
//@EnableDiscoveryClient opens the service discovery client
public class EbuyOrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(EbuyOrderApplication.class, args);
    }
}

4.2.5 start the EbuyOrderApplication class to register the service with Eureka

5. Cross service invocation

The basic microservices written above have been registered in Eureka registry.

Now there is a demand that users need to call the commodity micro service to obtain commodity data when placing an order. Through the above case, we should know that this is a call between cross service modules. Careful guys must have seen that we provide an HTTP interface for others to call in the controller layer of the commodity and adopt the Restful style, Therefore, you can use the relevant tool classes requested by HTTP when placing an order, such as common HttpClient, OkHttp, etc.

In fact, spring also provides us with a tool class RestTemplate.

5.1 introduction to RestTemplate

The RestTemplate class provided by the Spring framework can be used to invoke rest services in applications. It simplifies the communication with http services and unifies the standard of Restful. We only need to import url and return value types. Compared with the previously commonly used HttpClient, resttemplate is a more elegant way to call restful services.

Accessing third-party Rest services in Spring applications is related to using the Spring RestTemplate class. The design principle of RestTemplate class is the same as that of other Spring template classes (eg: JdbcTemplate, jmtemplate), which provides a simplified method with default behavior for performing complex tasks.

RestTemplate by default relies on the JDK's ability to provide http connection (HttpURLConnection). If necessary, it can also be replaced by other http libraries such as (eg: Apache HttpComponents, Netty or OKHttp) through the setRequestFactory method.

Considering that the RestTemplate class is designed to call REST services, it is not surprising that its main methods are closely connected with the basis of REST, which is the methods of HTTP protocol: HEAD, POST, PUT, DELETE and OPTIONS.

The RestTemplate class has the following methods:

  • headForHeaders()
  • getForObject()
  • postForObject()
  • put()
  • delete()

5.2 introduction to RestTemplate method

The main entry points of this template class are the following methods (corresponding to the six main methods of HTTP)

5.3. Calling microservices through RestTemplate

In the existing demand, users need to invoke commodity micro service to get product data when ordering. This time, we need to invoke the commodity module in the order module.

(1) It is preferred to create an EasyBuyProduct entity class in the pojo layer to receive results across service calls:

	package com.ebuy.order.pojo;
	
	import lombok.Data;
	import lombok.ToString;
	import java.io.Serializable;
	import java.math.BigDecimal;
	
	@Data
	@ToString
	public class EasybuyProduct implements Serializable {
	
	    private Long epId;
	
	    private String epName;
	
	    private String epDescription;
	
	    private BigDecimal epPrice;
	
	    private Long epStock;
	
	    private Long epcId;
	
	    private Long epcChildId;
	
	    private String epFileName;
	
	    private static final long serialVersionUID = 1L;
	}

(2) Configure the RestTemplate in Ebuy order's main startup class ebuyordapplication. When the service starts, the RestTemplate will be handed over to the spring container for management:

package com.ebuy.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
//@Enable Eureka client open Eureka client
//@EnableDiscoveryClient opens the service discovery client
public class EbuyOrderApplication {

    /**
     * Configure RestTemplate to spring management
     * @return
     */
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(EbuyOrderApplication.class, args);
    }
}

(3) In the OrderController class, first inject the RestTemplate class, and then write a method to call the product module:

package com.ebuy.order.controller;


import com.ebuy.order.pojo.EasybuyProduct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    RestTemplate restTemplate;

    /**
     * Direct cross project invocation
     * @param id
     * @PathVariable Map the parameter id in restful to the formal parameter list
     * @return
     */
    @RequestMapping(value = "/{id}",method = RequestMethod.GET)
    public EasybuyProduct findById(@PathVariable Long id) {
        EasybuyProduct easybuyProduct=new EasybuyProduct();
        //Call the Rest Service of product through getForObejct method of restTemplate class and receive the return value
        easybuyProduct=restTemplate.getForObject("http://127.0.0.1:9011/product/"+id,EasybuyProduct.class);
       return easybuyProduct;
    }

}

(4) Start Ebuy prodcut and Ebuy order services and access them in the address bar http://localhost:9012/order/816753

The above results show that the Ebuy order module successfully called the rest Service of Ebuy product and responded to the results!

5.4 disadvantages of RestTemplate calling Rest microservice

The above method using RestTemplate class calls the RESTFul API interface of commodity microservices, but we can clearly see that the provider's network address (ip, port) is hard coded into the code. This method has many problems:

  • Application scenarios are limited
  • Cannot dynamically adjust

5.5. Solve the problem of RestTemplate hard coding

You need to dynamically register and discover services through the registry.
The registration and heartbeat of EurekaClient and the acquisition of registration information on the server are implemented in the com.netflix.discovery.DiscoveryClient.initScheduledTasks() method.

By default, DiscoveryClient obtains the server registration information every 30 seconds, and the heartbeat time is 30 seconds. After the Client starts, it sends the registration information to the server 40 seconds later.

Rewrite the service call using DiscoveryClient in the OrderController class:

package com.ebuy.order.controller;


import com.ebuy.order.pojo.EasybuyProduct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
@RequestMapping("/order")
public class OrderController {

    /**
     * Calling remote services directly through restTemplate is too hard coded and inflexible;
     * Obtain the server registration information by default through DiscoveryClient,
     * Services required for dynamic mobilization (dynamic acquisition of ip address and port)
     */
    @Autowired
    private DiscoveryClient discoveryClient;


    @RequestMapping(value = "/dc/{id}",method = RequestMethod.GET)
    public EasybuyProduct findDcById(@PathVariable Long id) {
        //The name of the service to call
        List<ServiceInstance> list=discoveryClient.getInstances("ebuy-product");
        //At present, we only start one service, so just get(0) to get the first service
        ServiceInstance serviceInstance=list.get(0);
        /**
         * serviceInstance.getHost() Get service IP (dynamic)
         * serviceInstance.getPort() Get service port (dynamic)
         */
        EasybuyProduct  easybuyProduct=restTemplate.getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/product/"+id,EasybuyProduct.class);
        return  easybuyProduct;
    }
}

We have configured Eureka client related configurations in the above two microservices. At this time, we need to start Eureka server service registry first, and then start Eureka client (product and order) two client services.

After successful startup, access the address in the browser address bar http://localhost:9000/

It indicates that the client service (product provider and order consumer) has successfully registered with the eureka registry.
Then access in the address bar http://localhost:9012/order/dc/816753

Dynamic call succeeded, OK!!!

5.6 Eureka's self-protection mechanism

After the microservice is successfully registered for the first time, a heartbeat will be sent every 30 seconds to register the instance information of the service to the center. The instance still exists through EurekaServer. If no update is sent for more than 90 seconds, the server will remove this service from the registration information.

During the operation of Eureka Server, it will count whether the proportion of heartbeat failure is less than 80% within 15 minutes. If it is less than 80% (it is easy to meet during single machine debugging, which is actually caused by network instability in the production environment), Eureka Server will protect the current instance registration information and prompt a series of red ink warnings. The protection mode is mainly used to protect a group of Eureka Client and Eureka Server server in the scenario of network partition. Once entering the protection mode, Eureka Server will try to protect the information in its registry and will not delete the data in the service registration information (that is, it will not log off any microservices).

After verifying that the self-protection mechanism is enabled, it will not be displayed on the web immediately, but you need to wait for 5 minutes (you can configure it in the yml file as follows)

eureka:
  server:
    wait-time-in-ms-when-sync-empty: 5  #The default is 5 minutes

That is, refresh the visual supervision boundary of the registration center again after 5 minutes, and the following prompt message will appear:

You can also turn off the self-protection mechanism:

  server:
    enable-self-preservation: false #Turn off self-protection mechanism

Well, let's get here first!!!

Topics: Java Spring Cloud Microservices eureka RestTemplate