This article has participated in the activity of "New person creation Ceremony", and started the road of digging gold creation together.

1. Basic knowledge of Eureka

1.1. What is service governance?

In the traditional RPC remote call framework, it is complicated to manage the dependency relationship between each service and service, so it is necessary to use service governance to manage the dependency relationship between services, which can realize service invocation, load balancing, fault tolerance, etc., and realize service discovery and registration.

  • SpringCloudEncapsulates theNetflixcompany-developedEurekaModule to implement service governance.

1.2. What is Service registration and discovery?

  • Eureka ServerAs the server for the service registry function, it is the service registry. While other microservices in the system are usedEurekaThe client connects toEureka ServerAnd maintain a heartbeat connection. So that the system maintenance personnel can passEureka ServerTo monitor the normal operation of each micro-service in the system.

Service registration and discovery

In service registration and discovery, there is a registry. When the server is started, it aliases the information of the current server to the registry, such as the service address and communication address. The other party (consumer, service provider) uses this alias to get the actual service communication address from the registry, and then implements the local RPC call RPC. The core design idea of the remote invocation framework is: it is in the registry, because a registry is used to manage a dependency between each service (service governance concept). In any RPC remote framework, there is a registry that holds information about the service address (interface address).

1.3 Eureka two components

Eureka consists of two components: Eureka Server and Eureka Client.

  • Eureka Server: Provides service registration service. After each micro-service node is configured and started, it will be displayed inEureka ServerInformation about all available service nodes will be stored in the service registry in. You can view the information about service nodes on the interface.
  • Eureka Client: Access through the registry. Is a Java client for simplicityEureka ServerThe client also has a built-in load balancer that uses a round-robin load algorithm. After the application is started, theEureka ServerSend heartbeat (default interval is 30 seconds). ifEureka ServerIf the heartbeat of a node is not received within multiple heartbeat cycles,Eureka Server

2. Single Eureka construction steps

1. To build the Module

  • The name forcloud-eureka-server7001

2. Change the POM


      
<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>cloud02</artifactId>
        <groupId>com.xiao</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>


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

    <dependencies>
        <! -- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>com.xiao</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <! -- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <! -- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <! -- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <! -- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <! -- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <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>


Copy the code

3. Change to YML

server:
  port: 7001

eureka:
  instance:
    hostname: localhost  #eureka server instance name
  client:
    Do not register yourself with the registry
    register-with-eureka: false
    # represents a registry that maintains service instances and does not need to retrieve services
    fetch-registry: false
    service-url:
      This address is used by the eureka server
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
Copy the code

4. The main launch

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

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

5. Test results

6. Package structure screenshot

3. Payment module is settled in Eureka Server

1. To build the Module

  • We have already written about the payment module, which is used directly. The name forcloud-provider-payment8001.

2. Change the POM

New content

	  	<! -- New dependency added -->
        <! -- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
Copy the code

3. Change to YML

New content

# New additions
eureka:
  client:
    # sign up for Eureka Server
    register-with-eureka: true
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka
Copy the code

4. The main launch

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

@SpringBootApplication
@EnableEurekaClient
public class PaymentMain8001 {
    public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class,args); }}Copy the code

5. Test results

4. Order module entered Eureka Server

1. To build the Module

  • Order module has been written before, directly used. The name forcloud-consumer-order80.

2. Change the POM

New content

    	<! -- New dependency added -->
        <! -- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>


Copy the code

3. Change to YML

New content

spring:
  application:
    name: cloud-order-service

eureka:
  client:
    register-with-eureka: true
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:7001/eureka
Copy the code

4. The main launch

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

@SpringBootApplication
@EnableEurekaClient
public class OrderMain80 {
    public static void main(String[] args) { SpringApplication.run(OrderMain80.class,args); }}Copy the code

5. Test results

5. Cluster Eureka construction

5.1 Working principle of Eureka

  1. To start the firsteurekaThe registry
  2. Start the service providerpaymentPayment service
  3. When the payment service starts, it registers its own information (such as the service address) with an aliaseureka)
  4. consumersorderWhen a service needs to invoke an interface, it uses the service alias to go to the registry to get the actualRPCRemote call address.
  5. Once the consumer gets the call address, the underlying layer actually exploitsHttpClientTechnology implements remote calls.
  6. After the consumer obtains the service address, it is cached locallyjvm, default every interval30Update the service invocation address every second.

5.2 Eureka Cluster principle Description

  • multipleEureka ServerRegister with each other, watch out for each other, and present aEurekaService to achieve high availability.

5.3 Steps for Setting up Eureka cluster

1. Preparation

Modify the mapping file on the host

The added content is

127.0.0.1  eureka7001.com
127.0.0.1  eureka7002.com
Copy the code

2. To build the Module

  • newModule, the name forcloud-eureka-server7002.

3. Change the POM

  • cloud-eureka-server7002thepomThe file stays the same,cloud-eureka-server7002thepomFiles andcloud-eureka-server7001The same.

4. YML instead

  • cloud-eureka-server7001theYMLfile
server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com    #eureka server instance name
  client:
    register-with-eureka: false    Do not register yourself with the registry
    fetch-registry: false   # represents a registry that maintains service instances and does not need to retrieve services
    service-url:
      defaultZone: http://eureka7002.com:7002/eureka/    This address is used by the eureka server
 
 
Copy the code
  • cloud-eureka-server7002theYMLfile
server:
  port: 7002

eureka:
  instance:
    hostname: eureka7002.com #eureka server instance name
  client:
    register-with-eureka: false    Do not register yourself with the registry
    fetch-registry: false   # represents a registry that maintains service instances and does not need to retrieve services
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/     This address is used by the eureka server
 
 
Copy the code

5. Main startup class

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

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

6. Test results

5.4. Settle the payment module into Eureka Server

Modify the YML file to the following

server:
  port: 8001


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

eureka:
  client:
    # sign up for Eureka Server
    register-with-eureka: true
    fetchRegistry: true
      Stand-alone version # defaultZone: http://localhost:7001/eureka
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka  # version of the cluster


mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.xiao.cloud.entities



Copy the code

5.5. Enter the order module into Eureka Server

Modify the YML file to the following

server:
  port: 80


spring:
  application:
    name: cloud-order-service

eureka:
  client:
    register-with-eureka: true
    fetchRegistry: true
    service-url:
      Stand-alone version # defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka  # version of the cluster



Copy the code

5.6 Steps for cluster establishment of payment service providers

1. Create a Module named New Cloud-provider-Payment8002

  • With thecloud-provider-payment8001The only difference isymlThe port number of the file is8002.

2. Modify the Controller class of the payment module

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

@RestController
@Slf4j
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

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

    @PostMapping("/payment/create")
    public CommonResult create(@RequestBody Payment payment){
        int result = paymentService.create(payment);
        log.info("***** inserts result:" + result);
        if(result > 0) {return new CommonResult(200."Database inserted successfully, port number:" + ServerPort,result);
        }else {
            return new CommonResult(444."Failed to insert database".null); }}@GetMapping("/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);
        log.info("***** Query result:" + payment);
        if(payment ! =null) {return new CommonResult(200."Database query succeeded with port number:" + ServerPort,payment);
        }else {
            return new CommonResult(444."Failed to query database, no corresponding record, ID:" + id,null); }}}Copy the code
  • The port number is also output when the query is made.
  • Except for the above modification, all other parts are equalcloud-provider-payment8001The same.

3. Modify the URL in the Controller class of the order module

public static final String URL = "http://CLOUD-PAYMENT-SERVICE";
Copy the code
  • Here we access the microservice by name.

4. Modify the configuration class of the order module

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;

@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(a){
        return newRestTemplate(); }}Copy the code
  • One more is added@LoadBalancedAnnotation, thus implementingLoad balancing.

5. Test results

The payment module is called by the order module several times with different port numbers each time. In this way, load balancing is implemented.

5.7. Complete information of micro services of the ACTUATOR

Add the following content to the YML configuration files of cloud-provider-Payment8001 and cloud-provider-Payment8002

eureka:
  instance:
    instance-id: payment8001 Cloud-provider-payment8002 = payment8002
    prefer-ip-address: true
Copy the code
  • Modify the service name.
  • And at the time of the visitipDisplay.

5.8. Service Discovery Configuration

1. Use

  • We can get throughDiscoveryConfigure to get details about the service.

2. New additions to the Controller class

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/payment/discovery")
    public Object discovery(a){
        List<String> services = discoveryClient.getServices();
        for (String service : services) {
            log.info(***** services: + service);
        }

        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        for (ServiceInstance instance : instances) {
            log.info("**** Details:" + instance.getServiceId() + "\t" + instance.getHost() + "\t" + instance.getPort() + "\t" + instance.getUri());
        }
        return this.discoveryClient;
    }
Copy the code

3. New annotations on the main startup class

@EnableDiscoveryClient
Copy the code

4. Test results

5.9. Eureka protects itself

5.9.1, phenomena,

5.9.2 Contents of the self-protection mechanism

  • Bottom line: at some point a micro-service becomes unavailable,EurekaIt will not be cleaned up immediately, and the information about the micro-service will still be saved.
  • Belong toCAPThe inside of theAPBranch.
  • The self-protection mechanism is a security protection measure against network exceptions.

5.9.3 Why is a self-protection mechanism needed?

  • In order to preventEurekaClientCan proceed normally, but withEurekaServerWhen the network is disconnected,EurekaServerNot immediatelyEurekaClientService culling.

5.9.4. How to protect yourself?

Add the following contents to the Eureka server YML file

eureka:
  server:
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 2000
	
Copy the code

Add the following content to the Eureka client YML file

eureka:
  instance:
  # Eureka Specifies the interval, in seconds, at which the client sends the heartbeat to the server
    lease-expiration-interval-in-seconds: 1
  #Eureka server waiting time limit after receiving the last heartbeat, in seconds
    lease-expiration-duration-in-seconds: 2
	
Copy the code