Chapter V Eureka Service Registration and Discovery (SpringCloud, Silicon Valley)

1. Eureka Basics

  1. What is Service Governance

1.springcloud encapsulates the Eureka module developed by Netflix to implement service governance.
2. In the traditional rpc remote fishing common framework, the management of dependencies between each service and service is more complex, so it is necessary to use service governance, manage the dependencies between services, realize service invocation, load balancing, fault tolerance, and realize service discovery and registration.

  1. What is service registration and discovery

1.Eureka uses the CS design architecture. Eureka Server serves as the service registration function and is the service registration center.Other micro services in the system use Eureka's client connections to Eureka Server and maintain a heartbeat connection.In this way, the maintainer of the system can use Eureka Server to monitor the normal operation of each micro-service in the system.
2. In service registration and discovery, there is a registry.When the server starts, it registers the current information of its own server, such as the address of the service, address, and so on, with an alias in the registry.On the other hand (consumer | service provider), obtain the actual service communication address on the registry by this alias, and then implement the core design idea of the RPC Call Remote Call Framework for Local RPCs: lies in the registry, because the registry is used to manage a dependency between each service and service (service governance concept).In any RPC remote framework, there will be a registry (which holds information about service addresses (interface addresses))

ps: The Eureka system architecture is shown on the left and Dubbo on the right. Please compare:

  1. Eureka contains two components: Eureka Server and Eureka Client

1.Eureka Server provides service registration services:
Answer: After each micro service node is started by configuration, it will be registered in EurekaServer, so the service registry in EurekaServer will store all available service nodes'information, and the information of service nodes can be visually seen in the interface.
2.Eureka Client is accessed through the registry:
A: is a java client that simplifies interaction with Eureka Server and also has a built-in load balancer that uses round-robin load algorithms.After the application starts, a heartbeat is sent to Eureka Server (the default cycle is 30 seconds).If Eureka Server does not receive a node's heartbeat during multiple heartbeat cycles, Eureka Server will remove the service node from the service registry (default 90 seconds).

2. Steps to build single-machine Eureka

1.IDEA Generates the eurekaServer End Service Registry
Similar property companies
ps:eureka Server Service-side Installation
1. Set up a module

cloud-eureka-server7001

2. Change pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mscloud03</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-server7001</artifactId>

    <dependencies>
        <!--eureka-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- Introduce self-defined api Generic packages that can be used Payment payment Entity -->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--boot web actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--General General Configuration-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>
</project>

Contrast explanation of ps:1.x and 2.x

 
Older version before (currently using 2018)
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
 
 
 
New version now (currently using 2020).2)
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

3. Write yml

server:
  port: 7001

eureka:
  instance:
    hostname: localhost #Instance name of eureka server side
  client:
    #false means that you do not register yourself with the registry.
    register-with-eureka: false
    #false says that my client is the registry and my responsibility is to maintain service instances without having to retrieve services
    fetch-registry: false
    service-url:
    #This address is required for setting up an address query service and registration service to interact with Eureka Server.
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

4. Main Startup Class

package com.atguigu.springcloud;

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

/**
 * @auther 
 * @create 2020-01-28 20:40
 */
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001
{
    public static void main(String[] args)
    {
        SpringApplication.run(EurekaMain7001.class,args);
    }
}

5. Testing

Website:http://localhost:7001/
Result: Successful access to eureka interface indicates successful installation

2.EurekaClient-side cloud-provider-payment8001
Register with EurekaServer as a service provider, similar to Silicon Valley schools offering teaching services
1. Set up a module

cloud-provider-payment8001

2. Change pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.itcast.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-payment8001</artifactId>

    <dependencies>
        <!--eureka-client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency><!-- Introduce self-defined api Generic packages that can be used Payment payment Entity -->
            <groupId>com.itcast.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--mysql-connector-java-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

3. Write yml

server:
  port: 8001

#service name
spring:
  application:
    name: cloud-payment-service
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # Current data source operation type
    driver-class-name: org.gjt.mm.mysql.Driver              # MySQL driver package com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root

eureka:
  client:
    #Indicates whether to register yourself in EurekaServer by default to true.
    register-with-eureka: true
    #Whether to grab existing registration information from EurekaServer or not, defaults to true.Single node doesn't matter, cluster must be set to true to use load balancing with ribbon
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.itcast.springcloud.entities    # Package in which all Entity alias classes are located

4. Main Startup

package com.itcast.springcloud;

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

/**
 * @author henry
 * @version 1.0
 * @date 2021/8/28 0028 16:33
 */
@SpringBootApplication
@EnableEurekaClient
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class,args);
    }
}

5. Testing

1. Start EurekaServer first
2.http://localhost/7001
Result:

6. Configuration instructions for microservice registry name

7. Self-protection mechanism

3.EurekaClient-side cloud-consumer-order80
Enroll in Eureka Server as a consumer of services, similar to classmates in Silicon Valley
1. Set up modules

cloud-consumer-order80

2. The pom file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mscloud03</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-consumer-order80</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency><!-- Introduce self-defined api Generic packages that can be used Payment payment Entity -->
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

3. Modify the yml file

server:
  port: 80

spring:
  application:
    name: cloud-order-service

eureka:
  client:
    #Indicates whether to register yourself in EurekaServer by default to true.
    register-with-eureka: true
    #Whether to grab existing registration information from EurekaServer or not, defaults to true.Single node doesn't matter, cluster must be set to true to use load balancing with ribbon
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

4. Modify the main startup class

package com.itcast.springcloud;

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

/**
 * @author henry
 * @version 1.0
 * @date 2021/8/28 0028 21:11
 */
@SpringBootApplication
@EnableEurekaClient
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class,args);
    }
}

5. Testing

1. Start Eureka Server, 7001 Service first
2. Restart service provider, 8001 service
3. The Eureka server information is as follows:

4. Enter the web address:http://localhost/consumer/payment/get/31 The results presented below indicate that the service was successfully registered:

4.bug

1. Item tips are as follows:
Failed to bind properties under 'eureka.client.service-url' to java.util.Map<java.lang.String, java.lang.String>
2. Reason:

3. Construction steps of cluster Eurake

1. Explanation of Eureka Cluster Principle:

Question: What is the core of micro service RPC remote service calls

High Availability: High Availability, imagine that your registry only has one, it fails and that "ho-ho" will make the whole microservice environment unavailable, so
Solution: Build Eureka registry cluster to achieve load balancing + fault tolerance.

ps: How clusters are registered (in one sentence):

Register and watch each other

2.EurekaServer cluster environment building steps:
1. New cloud-eureka-server 7002

Reference cloud-eureka-server 7001

2. Change pom

 
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mscloud03</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-server7002</artifactId>


    <dependencies>
        <!--eureka-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- Introduce self-defined api Generic packages that can be used Payment payment Entity -->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--boot web actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--General General Configuration-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>
</project>

3. Modify mapping configuration

1. Find the hosts file under the path C:\Windows\System32\driversetc

2. Modify mapping configuration to add to hosts file
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com

4. Write yml (formerly single machine)
ps: mainly modify the hostname parameter and defaultZone parameter
7001yml:

server:
  port: 7001


eureka:
  instance:
    hostname: eureka7001.com #Instance name of eureka server side
  client:
    register-with-eureka: false     #false means that you do not register yourself with the registry.
    fetch-registry: false     #false says that my client is the registry and my responsibility is to maintain service instances without having to retrieve services
    service-url:
      defaultZone: http://eureka7002.com:7002/eureka/

7002yml:

server:
  port: 7002


eureka:
  instance:
    hostname: eureka7002.com #Instance name of eureka server side
  client:
    register-with-eureka: false     #false means that you do not register yourself with the registry.
    fetch-registry: false     #false says that my client is the registry and my responsibility is to maintain service instances without having to retrieve services
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

5. Main Startup Class

/**
 * @author henry
 * @version 1.0
 * @date 2021/9/4 0004 21:31
 */
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7002 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaMain7002.class,args);
    }
}

6. Testing
Successful access is possible through the following domain names (port 7002 is the same as registering with each other)

3. Publish the payment service 8001 micro service to the two Eureka cluster configurations above:
1. Modify the yml file

Modify parameters:
defaultZone: http://Eureka 7001.com:7001/eureka,http://eureka7002.com:7002/eureka  #Cluster Edition

4. Publish Order Service 80 micro-service to the two Eureka cluster configurations above:
1. Modify the yml file

Modify parameters:
defaultZone: http://Eureka 7001.com:7001/eureka,http://eureka7002.com:7002/eureka  #Cluster Edition

5.Test 01:

1. Start Eureka Server first, 7001/7002 service
2. To start the service provider again, 8001
3. To start consumers again, 80
4. Input http://eureka7002.com:7002/and http://eureka7001.com:7001/You can see that both 8001 and 80 services are registered at the service center
5. Enter the web address http://localhost/consumer/payment/get/31 Can return data normally

6. Setup of payment service provider 8001 cluster environment:
1. New module cloud-provider-payment8002

Reference cloud-provider-payment8001

2. Change the pom (refer to 8001)
3. Write yml (refer to 8001)
4. Main Start (Reference 8001)
5. Business Class (stick directly from 8001)
6. Modify the Controller for 8001/8002 (mainly by injecting the current service name and printing it out to visually see which service was called)

package com.itcast.springcloud.controller;

import com.itcast.springcloud.entities.CommonResult;
import com.itcast.springcloud.entities.Payment;
import com.itcast.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * @author rui
 * @version 1.0
 * @date 2021/8/28 0028 17:53
 */
@RestController
@Slf4j     //Print Log
public class PaymentController {

    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String serverPort;

    /*Request in restful style*/
    @PostMapping(value = "/payment/create")
    public CommonResult create(@RequestBody Payment payment){
       int result  = paymentService.create(payment);
       log.info("*****Insert results:"+result);
       if (result > 0){
           return new CommonResult(200,"Insert database succeeded,serverPort:"+serverPort,result);
       }else {
           return new CommonResult(444,"Failed to insert database",null);
       }
    }

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id){
        Payment payment  = paymentService.getPaymentById(id);
        log.info("*****Insert results:"+payment);
        if (payment != null){
            return new CommonResult(200,"query was successful,serverPort:"+serverPort,payment);
        }else {
            return new CommonResult(444,"No corresponding records, query ID: "+id,null);
        }
    }
}

7. Load Balancing:
1. bug (Order Service Access Address cannot be written to death in consumer class)

//private static final String PAYMENT_URL = "http://localhost:8001";
    // Called by a microservice name registered on eureka
    private static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

2. Use the @LoadBalanced annotation to give RestTemplate load balancing capabilities
3.ApplicationContextBean (add @LoadBalanced comment)

package com.itcast.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @author henry
 * @version 1.0
 * @date 2021/8/28 0028 21:23
 */
@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced //Use the @LoadBalanced annotation to give RestTemplate load balancing capabilities
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
//The above @bean annotation is similar to the following configuration file, adding this object to the spring container
//applicationtext.xml <bean id = "" class="">

8.Test 02:

1. Start Eureka Server first, 7001/7002 service
2. Start the service provider again, 8001/8002 service
3.http://localhost/consumer/payment/get/31
4. Result:
Load balancing is achieved (8001/8002 ports alternate)
5.Ribbon and Eureka are integrated so that Consumer s can call the service directly without worrying about the address and port number, and the service has load capabilities. (Later chapters)

4. Improvement of actuator micro-service information

1. Host Name: Service Name Modification
1. Current issues:

Contains host name
2. Modify and modify the yml file of cloud-provider-payment8001
ps: added instance attribute:

eureka:
  client:
    #Indicates whether to register yourself in EurekaServer by default to true.
    register-with-eureka: true
    #Whether to grab existing registration information from EurekaServer or not, defaults to true.Single node doesn't matter, cluster must be set to true to use load balancing with ribbon
    fetchRegistry: true
    service-url:
      defaultZone: http://Eureka 7001.com:7001/eureka,http://eureka7002.com:7002/eureka  #Cluster Edition
      #defaultZone: http://localhost:7001/eureka #Single machine version
  instance:
    instance-id: payment8001

3. Modified status

2. IP message prompt for access information
1. Current issues:
No ip prompt
2. Modify cloud-provider-payment8001
ps: Add the prefer-ip-address attribute under the instance attribute

eureka:
  client:
    #Indicates whether to register yourself in EurekaServer by default to true.
    register-with-eureka: true
    #Whether to grab existing registration information from EurekaServer or not, defaults to true.Single node doesn't matter, cluster must be set to true to use load balancing with ribbon
    fetchRegistry: true
    service-url:
      defaultZone: http://Eureka 7001.com:7001/eureka,http://eureka7002.com:7002/eureka  #Cluster Edition
      #defaultZone: http://localhost:7001/eureka #Single machine version
  instance:
    instance-id: payment8001
    prefer-ip-address: true     #Access paths can display IP addresses

3. After modification

V. Service Discovery

1. For micro-services registered in eureka, information about the service can be obtained through service discovery
2. Modify the Controller of cloud-provider-payment8001
ps: Add discovery to get service information

package com.atguigu.springcloud.controller;

import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @auther zzyy
 * @create 2020-01-27 21:17
 */
@RestController
@Slf4j
public class PaymentController
{
    @Value("${server.port}")
    private String serverPort;

    @Resource
    private PaymentService paymentService;

    @Resource
    private DiscoveryClient discoveryClient;

    @PostMapping(value = "/payment/create")
    public CommonResult create(@RequestBody Payment payment)
    {
        int result = paymentService.create(payment);
        log.info("*****Insert operation returns result:" + result);

        if(result > 0)
        {
            return new CommonResult(200,"Insert Successful,Return results"+result+"\t Service Port:"+serverPort,payment);
        }else{
            return new CommonResult(444,"Insert failed",null);
        }
    }

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id)
    {
        Payment payment = paymentService.getPaymentById(id);
        log.info("*****Query Results:{}",payment);
        if (payment != null) {
            return new CommonResult(200,"query was successful"+"\t Service Port:"+serverPort,payment);
        }else{
            return new CommonResult(444,"No corresponding record,query ID: "+id,null);
        }
    }

    @GetMapping(value = "/payment/discovery")
    public Object discovery()
    {
        List<String> services = discoveryClient.getServices();
        for (String element : services) {
            System.out.println(element);
        }

        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        for (ServiceInstance element : instances) {
            System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
                    + element.getUri());
        }
        return this.discoveryClient;
    }
}

3.8001 Main Startup Class

Add the @EnableDiscoveryClient comment

4. Self-Test

1. Start Eureka Server first
2. It will take a while to start the 8001 main startup class again
3.http://localhost:8001/payment/discovery
Ideal results:
The following two services appear at the reception desk:

Background can print the corresponding log:

6. eureka's self-protection

1. Failure Phenomena

1. Overview
The protection mode is mainly used for protection in a network partition scenario where a set of clients and Eureka Server exist.Once in protected mode, Eureka Server will attempt to protect the information in its service registry without deleting the data in the service registry, that is, without unregistering any microservices.
2. If you see the following prompt on the first page of Eureka Server, Eureka is in protection mode:
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT.
RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE

2. Causes

1. Why is there an Eureka self-protection mechanism?
To prevent the EurekaClient from functioning properly, but not immediately excluding the EurekaClient service if it is not connected to the EurekaServer network
2. What is a self-protection model?
By default, if EurekaServer does not receive a heartbeat for a microservice instance for a certain period of time, EurekaServer will log off the instance (default 90 seconds).However, when network partition failures occur (latency, carton, congestion), the normal communication between the microservice and EurekaServer can become very dangerous because the microservice itself is healthy and should not have been logged off at this time.Eureka solves this problem through "self-protection mode" - when an Eureka Server node loses too many clients in a short period of time (network partition failure may occur), it enters self-protection mode.

3. In self-protection mode, Eureka Server protects information in the service registry and no longer logs off any service instances.
Its design philosophy is to retain incorrect service registration information rather than blindly deregister any potentially healthy service instances.One sentence: Better to live than to die
4. To sum up, self-protection mode is a kind of security protection against network anomalies.Its architecture philosophy is to prefer to keep all microservices (both healthy and unhealthy) at the same time without blindly deregistering any healthy microservices.Using self-protection mode, you can make the Eureka cluster more robust and stable.

ps:1.In a word: Eureka will not like to clean up a microservice when it is unavailable, but will still save the information of the microservice
2. The AP branch that belongs to pairs within the CAP

3. How to prohibit self-protection

1. Registry EreakeServer side 7001

1. By default, the self-protection mechanism is on
2. Use eureka.server.enable-self-preservation = false to disable self-protection mode

3. Closing effect

4. Turn off self-protection at ErekaServer 7001

2. Producer client eureakeClient end 8001

1. Default
eureka.instance.lease-renewal-interval-in-seconds=30 (default 30 seconds)
eureka.instance.lease-expiration-duration-in-seconds=90 (default 90 seconds)
2. Configuration

3. Testing
Both 7001 and 8001 are configured;
Start 7001 before 8001

Close 8001 first (deleted immediately)

Tags: Java Zookeeper Spring Cloud eureka

Posted on Sat, 04 Sep 2021 12:58:44 -0400 by phuggett