Microservice notes 02

01. Hystrix circuit breaker

1. General

Problems faced by distributed systems

Problems faced by distributed systems
Applications in complex distributed architecture have dozens of dependencies, and each dependency will inevitably fail at some time.

Service avalanche

When calling between multiple microservices, suppose that microservice A calls microservice B and microservice C, and microservice B and microservice C call other microservices, which is the so-called "fan out". If the call response time of A microservice on the fan out link is too long or unavailable, the call to microservice A will occupy more and more system resources, resulting in system crash, the so-called "avalanche effect"

For high traffic applications, a single back-end dependency may cause all resources on all servers to saturate in a few seconds. Worse than failure, these applications may also lead to increased delays between services, tight backup queues, threads and other system resources, resulting in more cascading failures of the whole system. These indicate the need to isolate and manage failures and delays so that the failure of a single dependency cannot cancel the entire application or system.
So,
Usually, when you find that an instance under a module fails, the module will still receive traffic, and then the problematic module calls other modules, which will lead to cascade failure, or avalanche.

Hystrix

Hystrix is an open source library for dealing with delay and fault tolerance of distributed systems. In distributed systems, many dependencies inevitably fail to call, such as timeout and exception. Hystrix can ensure that in the case of a dependency failure, it will not lead to overall service failure, avoid cascading failures, and improve the elasticity of distributed systems.

"Circuit breaker" itself is a kind of switching device. When a service unit fails, it returns an expected and treatable alternative response (FallBack) to the caller through the fault monitoring of the circuit breaker (similar to fusing fuse), rather than waiting for a long time or throwing an exception that the caller cannot handle, This ensures that the thread of the service caller will not be occupied unnecessarily for a long time, so as to avoid the spread and even avalanche of faults in the distributed system.

I still didn't understand the function of Hystrix after reading it.

Through fault detection, an expected and processable alternative response (Fallback) is returned to the calling method

What can I do

  • service degradation
  • Service fuse
  • Near real-time monitoring

Official website information

2. Important concepts of hystrix

service degradation

  • The server is busy. Please try again later. Don't let the client wait and return a friendly prompt immediately
  • Under what circumstances will a downgrade be issued
    • Abnormal program operation
    • overtime
    • Service fuse triggers service degradation
    • Full thread pool / semaphore will also cause service degradation

Service fuse

  • Analog fuses achieve maximum service access, directly deny access, pull down the power limit, then call the service degradation method and return friendly hints.
  • It is the fuse. The degradation of the service = > and then the fuse = > restore the call link

Service current limiting

  • Second kill, high concurrency and other operations. It is strictly forbidden to rush over and crowd. Everyone queue up, N per second, in an orderly manner.

Summary chart

3. hystrix case

testing procedure

Creative project

Change POM

<dependencies>
    <!--hystrix-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <!--eureka client-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--web-->
    <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><!-- Introduce self defined api General package, you can use Payment payment Entity -->
        <groupId>com.lin</groupId>
        <artifactId>cloud-api-common</artifactId>
        <version>${project.version}</version>
    </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>

Write yml

server:
  port: 8005

spring:
  application:
    name: cloud-provider-hystrix-payment

eureka:
  client:
    register-with-eureka: true # Indicates that you are registered with Eureka Server
    fetch-registry: true # true means that my client is not a registry. My responsibility is not to maintain service instances and need to retrieve services
    service-url:
      #defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
      defaultZone: http://eureka7001.com:7001/eureka

Main start

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

Business class

 
package com.atguigu.springcloud.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.concurrent.TimeUnit;

/**
 * @auther zzyy
 * @create 2020-02-04 13:12
 */
@Service
public class PaymentService
{
    /**
     * Normal access, everything OK
     * @param id
     * @return
     */
    public String paymentInfo_OK(Integer id)
    {
        return "Thread pool:"+Thread.currentThread().getName()+"paymentInfo_OK,id: "+id+"\t"+"O(∩_∩)O";
    }

    /**
     * Timeout access, demotion
     * @param id
     * @return
     */
    public String paymentInfo_TimeOut(Integer id)
    {
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
        return "Thread pool:"+Thread.currentThread().getName()+"paymentInfo_TimeOut,id: "+id+"\t"+"O(∩_∩)O,It takes 3 seconds";
    }
}
 
package com.atguigu.springcloud.controller;

import com.atguigu.springcloud.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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

/**
 * @auther zzyy
 * @create 2019-11-22 13:02
 */
@RestController
@Slf4j
public class PaymentController
{
    @Autowired
    private PaymentService paymentService;

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


    @GetMapping("/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id)
    {
        String result = paymentService.paymentInfo_OK(id);
        log.info("****result: "+result);
        return result;
    }

    @GetMapping("/payment/hystrix/timeout/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException
    {
        String result = paymentService.paymentInfo_TimeOut(id);
        log.info("****result: "+result);
        return result;
    }
}

Normal test

Based on the above platform, recover from correct = > error = > degraded fuse = >

The default number of working threads of tomcat is full, and there are no extra threads to decompose the pressure and processing.

Create consumer services

  1. Create project

  2. Change POM

    • <dependencies>
          <!--openfeign-->
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-openfeign</artifactId>
          </dependency>
          <!--hystrix-->
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
          </dependency>
          <!--eureka client-->
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
          </dependency>
          <!-- Introduce self defined api General package, you can use Payment payment Entity -->
          <dependency>
              <groupId>com.lin</groupId>
              <artifactId>cloud-api-common</artifactId>
              <version>${project.version}</version>
          </dependency>
          <!--web-->
          <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 basic 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>
              <optional>true</optional>
          </dependency>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-test</artifactId>
              <scope>test</scope>
          </dependency>
      </dependencies>
      
  3. Write yml

    • server:
        port: 80
      
      eureka:
        client:
          register-with-eureka: false
          service-url:
            defaultZone: http://eureka7001.com:7001/eureka/
          fetch-registry: true # The default is true
      
  4. Main start

    • import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.netflix.hystrix.EnableHystrix;
      import org.springframework.cloud.openfeign.EnableFeignClients;
      
      /**
       * @auther zzyy
       * @create 2020-02-04 16:32
       */
      @SpringBootApplication
      @EnableFeignClients
      public class OrderHystrixMain80
      {
          public static void main(String[] args)
          {
              SpringApplication.run(OrderHystrixMain80.class,args);
          }
      }
      
  5. Service class

    • service

      • import org.springframework.cloud.openfeign.FeignClient;
        import org.springframework.stereotype.Component;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.PathVariable;
        
        /**
         * @auther zzyy
         * @create 2020-02-04 16:34
         */
        @Component
        @FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
        public interface PaymentHystrixService
        {
            @GetMapping("/payment/hystrix/ok/{id}")
            String paymentInfo_OK(@PathVariable("id") Integer id);
        
            @GetMapping("/payment/hystrix/timeout/{id}")
            String paymentInfo_TimeOut(@PathVariable("id") Integer id);
        }
        
    • controller

      • import com.atguigu.springcloud.service.PaymentHystrixService;
        import lombok.extern.slf4j.Slf4j;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.PathVariable;
        import org.springframework.web.bind.annotation.RestController;
        
        import javax.annotation.Resource;
        
        /**
         * @auther zzyy
         * @create 2020-02-20 11:57
         */
        @RestController
        @Slf4j
        public class OrderHystirxController
        {
            @Resource
            private PaymentHystrixService paymentHystrixService;
        
            @GetMapping("/consumer/payment/hystrix/ok/{id}")
            public String paymentInfo_OK(@PathVariable("id") Integer id)
            {
                String result = paymentHystrixService.paymentInfo_OK(id);
                return result;
            }
        
            @GetMapping("/consumer/payment/hystrix/timeout/{id}")
            public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
            {
                String result = paymentHystrixService.paymentInfo_TimeOut(id);
                return result;
            }
        }
        
  6. Normal test

  • Wait three seconds, that direct gg
  • The one you don't need is OK
  • Start the 2w stress test, visit the one that doesn't need to wait, turn around, and then visit gg it again

Cause analysis

8005 other interface services at the same level are trapped because the working threads in the tomcat thread pool have been occupied

80 at this time, call 8005, the client access response is slow, turn around

It is precisely because of the above failures or poor performance that our technologies such as degradation / fault tolerance / current limiting were born

Solution

  1. The timeout causes the server to slow down (turn around), and the timeout no longer waits
  2. Error (downtime or program running error), the error should be explained
  3. solve:
    • The other party's service (8001) has timed out, and the caller (80) cannot be stuck waiting all the time. There must be service degradation
    • The other party's service (8001) is down, and the caller (80) can't wait all the time. There must be service degradation
    • The other party's service (8001) is OK, the caller (80) has its own failure or self request (its own waiting time is less than that of the service provider), and handles the degradation by itself.

Service provider configures fallback

Business startup class:

 
package com.atguigu.springcloud.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.concurrent.TimeUnit;

/**
 * @auther zzyy
 * @create 2020-02-04 13:12
 */
@Service
public class PaymentService
{
    /**
     * Normal access, everything OK
     * @param id
     * @return
     */
    public String paymentInfo_OK(Integer id)
    {
        return "Thread pool:"+Thread.currentThread().getName()+"paymentInfo_OK,id: "+id+"\t"+"O(∩_∩)O";
    }

    /**
     * Timeout access, demotion
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
    })
    public String paymentInfo_TimeOut(Integer id)
    {
        int second = 5;
        try { TimeUnit.SECONDS.sleep(second); } catch (InterruptedException e) { e.printStackTrace(); }
        return "Thread pool:"+Thread.currentThread().getName()+"paymentInfo_TimeOut,id: "+id+"\t"+"O(∩_∩)O,It takes seconds: "+second;
    }
    //This method is called when the timeout occurs
    public String paymentInfo_TimeOutHandler(Integer id){
        return "/(ㄒoㄒ)/Timeout or exception in calling payment interface:\t"+ "\t Current thread pool name" + Thread.currentThread().getName();
    }
}

Once the call to the service method fails and an error message is thrown,
It will automatically call @ HystrixCommand to mark it
fallbackMethod calls the specified method in the class

Remember: close devtools

The hot deployment method we have configured has significantly changed the java code,
However, it is recommended to restart the microservice for the modification of the properties in @ HystrixCommand

Service consumer configures fallback

  • Write yml
# It means that openFeign can fuse, and the default is false
feign:
  hystrix:
    enabled: true
  • Control layer configuration
import com.lin.service.PaymentHystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@Slf4j
public class OrderHystrixController {
    @Resource
    private PaymentHystrixService paymentHystrixService;

    @GetMapping("/consumer/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id) {
        String result = paymentHystrixService.paymentInfo_OK(id);
        return result;
    }

    @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")
    })
    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    public String paymentInfo_Timeout(@PathVariable("id")Integer id) {
        String result = paymentHystrixService.paymentInfo_Timeout(id);
        return result;
    }
	//This is the fallback method, and the configuration is a one-to-one correspondence
    public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id) {
        return "I'm a consumer 80,The other party's payment system is busy. Please try again after 10 seconds, or your operation is wrong. Please check yourself,o(╥﹏╥)o";
    }
}
  • Main start

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
    import org.springframework.cloud.netflix.hystrix.EnableHystrix;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    //@Enablercircuitbreaker: after testing, this annotation is also OK
    @EnableHystrix //Open fuse, degraded operation
    //It seems that with this annotation, we don't need @ EnableEurekaClient, because we don't need RestTemplate
    @EnableFeignClients
    @SpringBootApplication
    public class OrderHystrixMain80 {
        public static void main(String[] args) {
            SpringApplication.run(OrderHystrixMain80.class,args);
        }
    }
    
    • There is a little doubt

    • @What is the difference between EnableHystrix and @ enablercircuitbreaker?

Current problems

Each business method corresponds to a bottom-up method, and the code expands

Separation of unified and customized

Solve the problem of code inflation

Configure a global, use it if necessary, and then use it in the controller layer

 
package com.atguigu.springcloud.controller;

import com.atguigu.springcloud.service.PaymentHystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @auther zzyy
 * @create 2020-02-04 16:35
 */
@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class PaymentHystirxController
{
    @Resource
    private PaymentHystrixService paymentHystrixService;

    @GetMapping("/consumer/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id)
    {
        String result = paymentHystrixService.paymentInfo_OK(id);
        return result;
    }

    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    @HystrixCommand //The @ DefaultProperties attribute annotation is added, and the specific method name is not written, so the unified global method is used
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
    {
        String result = paymentHystrixService.paymentInfo_TimeOut(id);
        return result;
    }
    public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id)
    {
        return "paymentTimeOutFallbackMethod,The other party's system is busy, please try again in 10 seconds/(ㄒoㄒ)/";
    }

    public String payment_Global_FallbackMethod()
    {
        return "Global Exception handling information, please try again later,/(ㄒoㄒ)/~~";
    }
}

When the service is degraded, the client calls the server and the server goes down or shuts down

In this case, the service degradation processing is completed at the client 80, which has nothing to do with the server 8001
Just add an implementation class for service degradation processing to the interface defined by Feign client to realize decoupling

The anomalies we will face in the future

Operation, timeout, downtime

resolvent

According to the existing PaymentHystrixService interface of cloud consumer feign hystrix order80,
Create a new class (PaymentFallbackService) to implement the interface and handle exceptions for the methods in the interface

Manage the fallback of the controller layer

The PaymentFallbackService class implements the PaymentFeignClientService interface

import com.lin.service.PaymentHystrixService;
import org.springframework.stereotype.Component;

@Component //Must add / / must add / / must add
public class PaymentFallbackService implements PaymentHystrixService {
    @Override
    public String paymentInfo_OK(Integer id) {
        return "Service call failed, prompt from: cloud-consumer-feign-order80";
    }

    @Override
    public String paymentInfo_Timeout(Integer id) {
        return "Service call failed, prompt from: cloud-consumer-feign-order80";
    }
}

yml configuration:

# For service degradation, add the fallbackFactory attribute value in the annotation @ FeignClient
feign:
  hystrix:
    enabled: true #Open Hystrix in Feign

feignClient configuration

@Component
@FeignClient(value = "cloud-provider-hystrix-payment",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {
    @GetMapping("/payment/hystrix/ok/{id}")
    String paymentInfo_OK(@PathVariable("id")Integer id);

    @GetMapping("/payment/hystrix/timeout/{id}")
    String paymentInfo_Timeout(@PathVariable("id") Integer id);
}

The last is the test

At this time, the service provider has been down, but we have degraded the service,
Let the client get prompt information when the server is unavailable without suspending the server

The above is service degradation

Service fuse

brief introduction

Overview of fuse mechanism
Fuse mechanism is a microservice link protection mechanism to deal with avalanche effect. When a microservice on the fan out link fails, is unavailable, or the response time is too long,
It will degrade the service, and then fuse the call of the node's microservice to quickly return the wrong response information.
When it is detected that the microservice call response of the node is normal, the call link is restored.

In the Spring Cloud framework, the circuit breaker mechanism is implemented through hystrix. Hystrix will monitor the status of calls between microservices,
The default threshold is that the call will fail within 20 seconds. The annotation of the fuse mechanism is @ HystrixCommand.

Great God thesis

Practical operation

Paste the code in the service of your 8005 port project

//=========Service fuse
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),// Is the circuit breaker on
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),// Number of requests
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),// Time window period
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),// What is the failure rate before tripping
    })
public String paymentCircuitBreaker(@PathVariable("id") Integer id) {
    if(id < 0)
    {
        throw new RuntimeException("******id Cannot be negative");
    }
    String serialNumber = IdUtil.simpleUUID();

    return Thread.currentThread().getName()+"\t"+"Call succeeded, serial number: " + serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id) {
    return "id Cannot be negative. Please try again later,/(ㄒoㄒ)/~~   id: " +id;
}

After several errors, it is found that the conditions are not met at the beginning, and even the correct access address cannot be accessed

//=========Service fuse
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),// Is the circuit breaker on
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),// Number of requests
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),// Time window period
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),// What is the failure rate before tripping
    })

Turn on the fuse, your test will continue to degrade, and then the normal one will not work.

I'm addicted to watching TV dramas. I can't record clearly. Don't be angry with me in the future. I'm decadent now.

Fuse type

Interpretation of fuse notes

Three important parameters of circuit breaker are involved: snapshot time window, threshold value of total requests and threshold value of error percentage.
1: Snapshot time window: the circuit breaker needs to count some request and error data to determine whether to open, and the statistical time range is the snapshot time window, which defaults to the last 10 seconds. (second)

2: Threshold of total requests: within the snapshot time window, the threshold of total requests must be met to be eligible for fusing. The default is 20, which means that if the number of calls of the hystrix command is less than 20 within 10 seconds, the circuit breaker will not open even if all requests timeout or fail for other reasons. (first)

3: Error percentage threshold: when the total number of requests exceeds the threshold within the snapshot time window, for example, 30 calls occur. If timeout exceptions occur in 15 of the 30 calls, that is, more than 50% of the error percentage, the circuit breaker will be opened when the 50% threshold is set by default.

After the fuse is opened

1: When another request is called, the main logic will not be called, but the degraded fallback will be called directly. Through the circuit breaker, it can automatically find errors and switch the degraded logic to the main logic to reduce the response delay.

2: How to restore the original main logic?
For this problem, hystrix also realizes the automatic recovery function for us.
When the circuit breaker is opened and the main logic is fused, hystrix will start a sleep time window. In this time window, the degraded logic is temporary and becomes the main logic,
When the sleep time window expires, the circuit breaker will enter the half open state and release a request to the original main logic. If the request returns normally, the circuit breaker will continue to close,
The main logic is restored. If there is still a problem with this request, the circuit breaker will continue to open and the sleep time window will be timed again.

All configurations

//========================All
@HystrixCommand(fallbackMethod = "str_fallbackMethod",
                groupKey = "strGroupCommand",
                commandKey = "strCommand",
                threadPoolKey = "strThreadPool",

                commandProperties = {
                    // Set the isolation policy. THREAD indicates THREAD pool. SEMAPHORE: signal pool isolation
                    @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
                    // When the isolation strategy selects signal pool isolation, it is used to set the size of signal pool (maximum concurrent number)
                    @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "10"),
                    // Configure the timeout for command execution
                    @HystrixProperty(name = "execution.isolation.thread.timeoutinMilliseconds", value = "10"),
                    // Enable timeout
                    @HystrixProperty(name = "execution.timeout.enabled", value = "true"),
                    // Is the execution interrupted when it times out
                    @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "true"),
                    // Is the execution interrupted when it is cancelled
                    @HystrixProperty(name = "execution.isolation.thread.interruptOnCancel", value = "true"),
                    // Maximum concurrent number of callback method executions allowed
                    @HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests", value = "10"),
                    // Whether the service degradation is enabled and whether the callback function is executed
                    @HystrixProperty(name = "fallback.enabled", value = "true"),
                    // Is the circuit breaker enabled
                    @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
                    // This attribute is used to set the minimum number of requests for circuit breaker fusing in the rolling time window. For example, when the default value is 20,
                    // If only 19 requests are received within the rolling time window (default 10 seconds), the circuit breaker will not open even if all 19 requests fail.
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
                    // This attribute is used to set in the rolling time window, indicating that in the rolling time window, the number of requests exceeds
                    // circuitBreaker. In the case of requestvolumthreshold, if the percentage of wrong requests exceeds 50,
                    // Set the circuit breaker to the "on" state, otherwise it will be set to the "off" state.
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
                    // This attribute is used to set the sleep time window after the circuit breaker is opened. After the sleep window ends,
                    // It will set the circuit breaker to the "half open" state and try the request command of fusing. If it still fails, it will continue to set the circuit breaker to the "open" state,
                    // Set to "off" if successful.
                    @HystrixProperty(name = "circuitBreaker.sleepWindowinMilliseconds", value = "5000"),
                    // Forced opening of circuit breaker
                    @HystrixProperty(name = "circuitBreaker.forceOpen", value = "false"),
                    // Forced closing of circuit breaker
                    @HystrixProperty(name = "circuitBreaker.forceClosed", value = "false"),
                    // Rolling time window setting, which is used for the duration of information to be collected when judging the health of the circuit breaker
                    @HystrixProperty(name = "metrics.rollingStats.timeinMilliseconds", value = "10000"),
                    // This attribute is used to set the number of "buckets" divided when rolling time window statistics indicator information. When collecting indicator information, the circuit breaker will
                    // The set time window length is divided into multiple "buckets" to accumulate each measurement value. Each "bucket" records the collection indicators over a period of time.
                    // For example, it can be divided into 10 "buckets" in 10 seconds, so timeinMilliseconds must be divisible by numBuckets. Otherwise, an exception will be thrown
                    @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "10"),
                    // This property is used to set whether the delay in command execution is tracked and calculated using percentiles. If set to false, all summary statistics will return - 1.
                    @HystrixProperty(name = "metrics.rollingPercentile.enabled", value = "false"),
                    // This property is used to set the duration of the rolling window of percentile statistics, in milliseconds.
                    @HystrixProperty(name = "metrics.rollingPercentile.timeInMilliseconds", value = "60000"),
                    // This attribute is used to set the number of buckets used in the percentile statistics scroll window.
                    @HystrixProperty(name = "metrics.rollingPercentile.numBuckets", value = "60000"),
                    // This attribute is used to set the maximum number of executions to keep in each bucket during execution. If the number of executions exceeding the set value occurs within the rolling time window,
                    // Start rewriting from the original position. For example, set this value to 100 and scroll the window for 10 seconds. If 500 executions occur in a "bucket" within 10 seconds,
                    // Then only the statistics of the last 100 executions are retained in the "bucket". In addition, increasing the size of this value will increase the consumption of memory and the calculation time required to sort percentiles.
                    @HystrixProperty(name = "metrics.rollingPercentile.bucketSize", value = "100"),
                    // This attribute is used to set the interval waiting time for collecting health snapshots (success of requests, percentage of errors) that affect the status of the circuit breaker.
                    @HystrixProperty(name = "metrics.healthSnapshot.intervalinMilliseconds", value = "500"),
                    // Enable request cache
                    @HystrixProperty(name = "requestCache.enabled", value = "true"),
                    // Whether the execution and events of the HystrixCommand are printed into the HystrixRequestLog
                    @HystrixProperty(name = "requestLog.enabled", value = "true"),
                },
                threadPoolProperties = {
                    // This parameter is used to set the number of core threads in the command execution thread pool, which is the maximum concurrency of command execution
                    @HystrixProperty(name = "coreSize", value = "10"),
                    // This parameter is used to set the maximum queue size of the thread pool. When set to - 1, the thread pool will use the queue implemented by SynchronousQueue,
                    // Otherwise, the queue implemented by LinkedBlockingQueue will be used.
                    @HystrixProperty(name = "maxQueueSize", value = "-1"),
                    // This parameter is used to set the rejection threshold for the queue. With this parameter, the request can be rejected even if the queue does not reach the maximum value.
                    // This parameter is mainly a supplement to the LinkedBlockingQueue queue, because LinkedBlockingQueue
                    // The queue cannot dynamically modify its object size, but the size of the queue that rejects requests can be adjusted through this attribute.
                    @HystrixProperty(name = "queueSizeRejectionThreshold", value = "5"),
                }
               )
public String strConsumer() {
    return "hello 2020";
}
public String str_fallbackMethod() {
    return "*****fall back str_fallbackMethod";
}

Service current limiting

In the later advanced chapter, we will explain the Sentinel description of alibaba

4. hystrix workflow

How it works

1 create a HystrixCommand (used when the dependent service returns a single operation result) or HystrixObserableCommand (used when the dependent service returns multiple operation results) object.

2 command execution. Among them, hystrix comand implements the first two execution modes below; The HystrixObservableCommand implements the latter two execution methods: execute(): synchronous execution, returning a single result object from the dependent service, or throwing an exception when an error occurs. queue(): asynchronous execution, directly returning a Future object, which contains a single result object to be returned at the end of service execution. observe(): returns an Observable object, which represents multiple results of the operation, It is a Hot Observable (whether the "event source" has a "Subscriber" or not, the event will be published after creation. Therefore, each "Subscriber" of Hot Observable may start in the middle of the "event source" and may only see the partial process of the whole operation). toObservable(): the Observable object will also be returned, which also represents multiple results of the operation, However, it returns a Cold Observable (when there is no "Subscriber", the event will not be published, but wait until there is a "Subscriber", so for the subscriber of Cold Observable, it can ensure to see the whole process of the operation from the beginning).

3 if the request caching function of the current command is enabled and the command cache hits, the cached result will be immediately returned in the form of Observable object.

4 check whether the circuit breaker is open. If the circuit breaker is open, Hystrix will not execute the command, but transfer to the fallback processing logic (step 8); If the circuit breaker is closed, check whether resources are available to execute the command (step 5).

5. Check whether the thread pool / request queue / semaphore is full. If the command depends on the dedicated thread pool and request queue of the service, or the semaphore (when the thread pool is not used) is full, the Hystrix will not execute the command, but will transfer to the fallback processing logic (step 8).

6 Hystrix will decide how to request dependent services according to the method we write. HystrixCommand.run(): return a single result or throw an exception. HystrixObservableCommand.construct(): return an Observable object to emit multiple results, or send error notification through onError.

7 Hystrix will report "success", "failure", "rejection", "timeout" and other information to the circuit breaker, and the circuit breaker will maintain a set of counters to count these data. The circuit breaker will use these statistics to decide whether to open the circuit breaker to "fuse / short circuit" a service dependent request.

8 when the command fails to execute, Hystrix will enter fallback and try to fallback. We usually call this operation "service degradation". The conditions that can cause service degradation are as follows: Step 4: when the current command is in the "fuse / short circuit" state and the circuit breaker is open. Step 5: when the thread pool, request queue or semaphore of the current command is full. Step 6: hystrixobservercommand Construct() or hystrixcommand When run () throws an exception.

9 when the Hystrix command is executed successfully, it will return the processing result directly or in the form of Observable.

tips: if we do not implement the degradation logic for the command or throw an exception in the degradation processing logic, Hystrix will still return an Observable object, but it will not emit any result data. Instead, it will notify the command to immediately interrupt the request through the onError method, and send the exception causing the command failure to the caller through the onError() method.

5. Service monitoring hystrixDashboard

In addition to isolating the calls of dependent services, hystrix also provides a quasi real-time call monitoring (Hystrix Dashboard). Hystrix will continuously record the execution information of all requests initiated through hystrix and display it to users in the form of statistical reports and graphics, including how many requests are executed, how many successes, how many failures, etc. Netflix monitors the above indicators through the hystrix metrics event stream project. Spring Cloud also provides the integration of the Hystrix Dashboard to transform the monitoring content into a visual interface.

How to understand the displayed diagram

7 colors. It says on it. I won't introduce it more

One circle:

Filled circle: there are two meanings. It represents the health degree of the instance through the change of color, and its health degree decreases from green < yellow < orange < red.
In addition to the change of color, the size of the solid circle will also change according to the request flow of the instance. The larger the flow, the larger the solid circle. Therefore, through the display of the solid circle, we can quickly find fault cases and high pressure cases in a large number of examples.

frontline:

Curve: it is used to record the relative change of flow within 2 minutes. It can be used to observe the rising and falling trend of flow.

02. Gateway new generation gateway

Overview introduction

Three core concepts

Gateway workflow

Official website

Getting started configuration

A very important component in the Cloud family bucket is the gateway, which is in 1 Zuul gateway is adopted in version x;
But in 2 In version x, zuul's upgrade has been skipped. Spring cloud finally developed a gateway to replace zuul,
That's what spring cloud gateway says: gateway is the original zuul1 Replacement of version x

summary

Gateway is an API gateway service built on the Spring ecosystem and is based on technologies such as Spring 5, Spring Boot 2 and Project Reactor.
Gateway aims to provide a simple and effective way to route API s and provide some powerful filter functions, such as fusing, current limiting, Retry, etc

Spring Cloud gateway is a new project of Spring Cloud. It is a gateway developed based on Spring 5.0+Spring Boot 2.0 and Project Reactor. It aims to provide a simple and effective unified API routing management method for microservice architecture.

As a gateway in the Spring Cloud ecosystem, the goal of Spring Cloud gateway is to replace Zuul. In Spring Cloud versions above 2.0, the latest performance versions above Zuul 2.0 are not integrated, and Zuul 1.0 is still used X is an old version of non Reactor mode. In order to improve the performance of the gateway, the Spring Cloud gateway is implemented based on the WebFlux framework, and the bottom layer of the WebFlux framework uses the high-performance Reactor mode communication framework Netty.

The goal of Spring Cloud Gateway is to provide a unified routing method, and the Filter chain based method provides the basic functions of the gateway, such as security, monitoring / indicators, and current limiting.

in a word

The reactor Netty responsive programming component in Webflux used by spring cloud gateway uses Netty communication framework at the bottom

Source code architecture

I have learned weblux, but I can't use it now. It's very important to write a small project immediately after learning a technology.

What can I do

  • Reverse proxy
  • authentication
  • flow control
  • Fuse
  • Log monitoring
  • . . . . . . . . . . . . . .

Where is the gateway in microservices

Why did Zuul come out of the gateway again

On the one hand, because zuul1 0 has entered the maintenance stage, and the Gateway is developed by the spring cloud team. It is a son product and is trustworthy.
Moreover, many functions of Zuul are not used, and it is also very simple and convenient.

Gateway is developed based on asynchronous non blocking model. There is no need to worry about performance. Although Netflix has long released the latest zuul 2 x,
But Spring Cloud seems to have no integration plan. And Netflix related components are declared to enter the maintenance period; I wonder what the future holds?

Considering all aspects, Gateway is an ideal Gateway choice.

Spring Cloud Gateway has the following features:

Based on Spring Framework 5, Project Reactor and Spring Boot 2.0;
Dynamic routing: it can match any request attribute;
You can specify Predicate and Filter for the route;
Integrated circuit breaker function of Hystrix;
Integrate Spring Cloud service discovery function;
Easy to write Predicate and Filter;
Request current limiting function;
Path rewriting is supported.

The difference between Spring Cloud Gateway and Zuul

Before the official version of Spring Cloud Finchley, the gateway recommended by Spring Cloud was Zuul provided by Netflix:

1,Zuul 1.x. Is an API Gateway based on blocking I/ O

2,Zuul 1.x is based on servlet 2 5 using blocking architecture, it does not support any long connection (such as websocket). Zuul's design mode is more similar to that of Nginx. Each I/ O operation is executed by selecting one of the working threads, and the request thread is blocked until the working thread is completed. However, the difference is that Nginx is implemented in C + +, zuul is implemented in Java, and the JVM itself will be loaded slowly for the first time, The performance of zuul is relatively poor.

3,Zuul 2. The X concept is more advanced. It wants to be non blocking based on Netty and support long connections, but spring cloud has not been integrated yet. Zuul 2.x has better performance than zuul 1 X has been greatly improved. In terms of performance, according to the official benchmark, the RPS (requests per second) of Spring Cloud Gateway is 1.5 times that of zuul Six times.

4. Spring Cloud Gateway is built on Spring Framework 5, Project Reactor and Spring Boot 2 and uses non blocking API s.

5. Spring Cloud Gateway also supports WebSocket and is closely integrated with spring to have a better development experience

The Zuul version integrated in spring cloud uses Tomcat container and traditional Servlet IO processing model.

After studying the mid-term web course in Silicon Valley, I know a topic: the life cycle of servlets? The servlet is managed by the servlet container for its life cycle.
When the container starts, construct a servlet object and call servlet init() for initialization;
The container runtime accepts the request and assigns a thread for each request (usually obtains the idle thread from the thread pool) and then calls service().
When the container is closed, call servlet destroy() to destroy the servlet;

What is Webflux

Traditional Web frameworks, such as struts 2 and spring MVC, run on the basis of Servlet API and Servlet container.
however
In servlet3 After 1, there is asynchronous non blocking support. WebFlux is a typical non blocking asynchronous framework, and its core is implemented based on the relevant API of Reactor. Compared with the traditional web framework, it can run on such platforms as Netty, Undertow and servlet3 1 on the container. Non blocking + functional programming (spring 5 must let you use java8)

Spring WebFlux is a new responsive framework introduced by Spring 5.0. Different from Spring MVC, it does not need to rely on Servlet API. It is completely asynchronous and non blocking, and implements responsive flow specification based on Reactor.

Three core concepts

Route

Routing is the basic module for building a gateway. It consists of ID, target URI, a series of assertions and filters. If the assertion is true, the route will be matched

Predicate (assertion)

The reference is java 8 util. function. Predicate
Developers can match all the contents of the HTTP request (such as the request header or request parameters), and route the request if it matches the assertion

Filter

In the Spring gateway framework, the filter can be used before or after the request is routed.

population

The web request locates the real service node through some matching conditions. And before and after this forwarding process, some fine control is carried out.
predicate is our matching condition;
filter can be understood as an omnipotent interceptor. With these two elements and the target uri, a specific route can be implemented

gateway workflow

The client sends a request to the Spring Cloud Gateway. Then find the route matching the request in the Gateway Handler Mapping and send it to the Gateway Web Handler.

The Handler then sends the request to our actual service through the specified filter chain, executes the business logic, and then returns.
The filters are separated by dashed lines because the filter may execute business logic before ("pre") or after ("post") sending the proxy request.

The "pre" type of Filter can be used for parameter verification, permission verification, traffic monitoring, log output, protocol conversion, etc,
In the "post" type filter, you can modify the response content and response header, log output, traffic monitoring and so on.

I don't want to do cases. This is the third time I've learned gateway. I won't check it myself

The essence of gateway is routing and forwarding.

web dependency pit

When gateway is used in the project, the spring boot starter web dependency is removed

Dynamic routing through microservice name

Registry and gateway

By default, the Gateway will register the service list according to the registry,
Create a dynamic route with the micro service name on the registry as the path for forwarding, so as to realize the function of dynamic route

It should be noted that the protocol of uri is lb, which means that the load balancing function of Gateway is enabled.

lb://serviceName is the load balancing uri that spring cloud gateway automatically creates for us in microservices

Use of Predicate

What is it?

Spring Cloud Gateway takes route matching as part of the Spring WebFlux HandlerMapping infrastructure.
Spring Cloud Gateway includes many built-in route predict factories. All these predictions match the different attributes of the HTTP request. Multiple route predict factories can be combined

When Spring Cloud Gateway creates a Route object, it uses routepredictefactory to create a Predicate object, which can be assigned to Route. Spring Cloud Gateway includes many built-in Route predict factories.

All of these predicates match different attributes of the HTTP request. Multiple predicate factories can be combined and passed through logical and.

Assertion configuration

If you need to use it, go to the brain map

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #Enable the function of dynamically creating routes from the registry
      routes:
        - id: payment_routh #payment_route    #The ID of the route. There are no fixed rules, but it is required to be unique. It is recommended to match the service name
          # uri: http://localhost:8001 # matches the routing address of the service
          uri: lb://Cloud payment service # matches the routing address of the service
          predicates:
            - Path=/payment/get/**         # Assert that the path matches the route

        - id: payment_routh2 #payment_route    #The ID of the route. There are no fixed rules, but it is required to be unique. It is recommended to match the service name
          # uri: http://localhost:8001 # matches the routing address of the service
          uri: lb://Cloud payment service # matches the routing address of the service
          predicates:
            - Path=/payment/lb/**         # Assert that the path matches the route
            - After=2020-02-05T15:10:03.685+08:00[Asia/Shanghai]         # Assert that the path matches the route
            #- Before=2020-02-05T15:10:03.685+08:00[Asia/Shanghai]         # Assert that the path matches the route
            #- Between=2020-02-02T17:45:06.206+08:00[Asia/Shanghai],2020-03-25T18:59:06.206+08:00[Asia/Shanghai]
            #- Cookie=username,zzyy
            #- Header=X-Request-Id, \d+  # The request header must have an X-Request-Id attribute and a regular expression with an integer value
            #- Host=**.atguigu.com
            - Method=GET
            - Query=username, \d+  # You must have a parameter name username and the value must be an integer to route

To put it bluntly, predict is to implement a set of matching rules and let the request come and find the corresponding Route for processing.

Use of Filter

03. SpringCloud Config

  • SpringCloud Config distributed configuration center

summary

Microservice means to split the business in a single application into one sub service. The granularity of each service is relatively small, so there will be a large number of services in the system. Because each service needs the necessary configuration information to run, a centralized and dynamic configuration management facility is essential.

Spring cloud provides ConfigServer to solve this problem. Each microservice brings an application YML, management of hundreds of configuration files
/(ㄒoㄒ)/~~

What is it?

What is it?

SpringCloud Config provides centralized external configuration support for microservices in the microservice architecture, and the configuration server provides a centralized external configuration for all environments of different microservice applications.

How do you play?
SpringCloud Config is divided into two parts: server and client.

The server is also known as the distributed configuration center. It is an independent micro service application, which is used to connect to the configuration server and provide the client with access interfaces such as obtaining configuration information and encrypting / decrypting information

The client manages application resources and business-related configuration contents through the specified configuration center, and obtains and loads configuration information from the configuration center at startup. The configuration server uses git to store configuration information by default, which is helpful for version management of environment configuration, And the GIT client tool can be used to manage and access the configuration content conveniently.

What can I do

  • Centrally manage profiles
  • Different environments have different configurations, dynamic configuration updates and deployment by environment, such as dev/test/prod/beta/release
  • The configuration is dynamically adjusted during operation. It is no longer necessary to write configuration files on each service deployed machine. The service will uniformly pull and configure its own information from the configuration center
  • When the configuration changes, the service can sense the change of configuration and apply the new configuration without restarting
  • Expose the configuration information in the form of REST interface
    • post, curl access and refresh

Integrated configuration with GitHub

Because spring cloud config uses Git to store configuration files by default (there are other ways, such as supporting SVN and local files),
But Git is the most recommended, and it is accessed in the form of http/https

Official website

eureka.client.registerWithEureka: indicates whether to register yourself with Eureka Server. The default value is true. Since the current application is Eureka Server, it is set to false.
eureka.client.fetchRegistry: indicates whether to obtain registration information from Eureka Server. The default value is true. Because this is a single point Eureka Server, it does not need to synchronize the data of other Eureka Server nodes, so it is set to false.
eureka.client.serviceUrl.defaultZone: set the address to interact with Eureka Server. Both query service and registration service need to rely on this address. Default is http://localhost:8100/eureka ; Multiple addresses can be used and separated.

eureka. client. Fetch registry: the logic of "service acquisition" is in an independent if judgment, and its judgment basis is Eureka client. Fetch registry = true parameter, which is true by default. We don't need to care about it in most cases. In order to regularly update the service list of the client to ensure the correctness of service access, the request for "service acquisition" is not limited to service startup, but a regularly executed task. From the source code, we can see that the registryFetchIntervalSeconds parameter in the task operation corresponds to Eureka client. Registry fetch interval seconds = 30 configuration parameter, which defaults to 30 seconds.

These are the methods of how to write the request

  /{name}-{profiles}.yml
 
/{label}-{name}-{profiles}.yml
 
label: branch(branch)
name : service name
profiles: environment(dev/test/prod)

Config server configuration and test

bootstrap.yml

applicaiton.yml is a user level resource configuration item
bootstrap.yml is system level with higher priority

Spring Cloud will create a "Bootstrap Context" as the parent context of the Application Context of spring application. During initialization, Bootstrap Context is responsible for loading configuration properties from external sources and parsing the configuration. The two contexts share an Environment obtained from the outside.

Bootstrap properties have high priority and are not overridden by local configuration by default. Bootstrap Context and Application Context have different conventions, so a bootstrap is added YML file to ensure the separation of Bootstrap Context and Application Context configuration.

To add the application. Under the Client module Change the YML file to bootstrap YML, this is critical,
Because bootstrap YML is better than application YML is loaded first. bootstrap.yml takes precedence over application yml

Modify the config-dev.yml configuration and submit it to GitHub, such as adding a variable age or version number version

Config client configuration and testing

Bootstrap properties have high priority and are not overridden by local configuration by default. Bootstrap Context and Application Context have different conventions, so a bootstrap is added YML file to ensure the separation of Bootstrap Context and Application Context configuration.

Here, I want to explain that if @ Value can't find something in yml, it will directly report an error.

When we use @ Value to test the config remote configuration, we must pay attention to

spring:
  cloud:
    #Config client configuration
    config:
      label: master #Branch name
      name: config #Profile name
      profile: dev #Read the suffix name and the above three combinations: the configuration file of config-dev.yml on the master branch is read http://config-3344.com:3344/master/config-dev.yml
      uri: http://localhost:3344 # configuration center address k

This configuration file should be placed in the bootstrap, otherwise it will report an error and cannot be found.

Dynamic refresh of Config client

From this figure, we can know that our data is pulled remotely at the configuration server, but it is obtained from the server once at the configuration client, and then fixed.

I guess what the client reads is put in the cache.

Problems come at any time. Dynamic refresh of distributed configuration:

Avoid restarting the client micro service 3355 every time the configuration is updated

The way of realization

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
# Exposure monitoring endpoint
management:
  endpoints:
    web:
      exposure:
        include: "*"

Finally, add @ RefreshScope to the class that needs to be dynamically obtained by the client

You need to send a post request to refresh, otherwise you still can't get the modified configuration, and the url is: http://localhost:3355/actuator/refresh

However, it seems that it still needs to be done manually, and then it doesn't matter. After the change, the operation and maintenance personnel can post this url.

Any questions

04. SpringCloud Bus

Message bus

The deepening and expansion of the previous explanation can be summarized in a word

summary

Spring Cloud Bus can be used with Spring Cloud Config to dynamically refresh the configuration.

Spring Cloud Bus is a framework used to link nodes of distributed systems with lightweight messaging systems,
It integrates the event processing mechanism of Java and the function of message middleware.
Spring cloud bus currently supports RabbitMQ and Kafka.

Spring Cloud Bus can manage and propagate messages between distributed systems, just like a distributed actuator. It can be used to broadcast state changes, push events, etc. it can also be used as a communication channel between microservices.

What is a bus
In the system of microservice architecture, a lightweight message broker is usually used to build a common message topic and connect all microservice instances in the system. Since the messages generated in this topic will be monitored and consumed by all instances, it is called message bus. Each instance on the bus can easily broadcast some messages that need to be known by other instances connected to the subject.

Basic principles
ConfigClient instances listen to the same Topic in MQ (springcloudbus by default). When a service refreshes the data, it will put this information into the Topic, so that other services listening to the same Topic can be notified, and then update their own configuration.

MQ Yangge Video Explanation

RabbitMQ environment configuration

PS:By default, you have installed it docker On your own virtual machine or your own server
docker pull rabbitmq:3-management(Remote installation,The version can be selected independently)
--------------------------------------
You can also download it on your computer rabbitmq.tar,Then upload it to your virtual machine or server,then
docker load -i mq.tar

---------------------------
Next, we can use docker Run our RabbitMQ Yes
docker run \
 -e RABBITMQ_DEFAULT_USER=xxx \
 -e RABBITMQ_DEFAULT_PASS=xxx\
 --name mq \
 --hostname mq1 \
 -p 15672:15672 \        (Note: This is the management page port)
 -p 5672:5672 \          (Note: This is the communication port)
 -d \            (Background operation)
 rabbitmq:3-management

Don't copy the above operation instructions directly, xxx,xxx You can set these two independently and delete the brackets and the contents in the brackets
 Good luck
docker run -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=123456 --name mq --hostname mq1 -p 15672:15672 -p 5672:5672 -d rabbitmq:3.7.14-management

Note: only those with management can have pages

Spring cloud bus dynamically refreshes global broadcast

design idea

1) Use the message bus to trigger a client / bus/refresh and refresh the configuration of all clients

2) Use the message bus to trigger the / bus/refresh endpoint of a server ConfigServer and refresh the configuration of all clients

The architecture in Figure 2 is obviously more suitable. The reasons why Figure 1 is not suitable are as follows

  • It breaks the single responsibility of microservice, because microservice itself is a business module, which should not bear the responsibility of configuration refresh.
  • It destroys the equivalence of micro service nodes.
  • There are certain limitations. For example, when migrating a microservice, its network address often changes. At this time, if you want to refresh automatically, you will add more modifications

Why can this be achieved? I don't understand why it was broadcast. Just configure it like that.

I'm not even superficial.

This is the Lord

##rabbitmq related configuration, exposing the endpoint of bus refresh configuration
management:
  endpoints: #Exposed bus refresh configured endpoint
    web:
      exposure:
        include: 'bus-refresh'

This is from

# Exposure monitoring endpoint
management:
  endpoints:
    web:
      exposure:
        include: "*"

Spring cloud bus dynamic refresh fixed-point notification

  • destination: spring application. name:server. port. Example:“ http://localhost:3344/actuator/bus -Refresh / config client: 3355 ". Of course, you still need to use post request.

05. Spring cloud stream message driven

Message driven overview

What is spring cloudstream
Spring is an official message driven framework for building cloud stream services.

The application interacts with the binder object in Spring Cloud Stream through inputs or outputs.
We configure binding, and the binder object of Spring Cloud Stream is responsible for interacting with the message middleware.
Therefore, we only need to figure out how to interact with Spring Cloud Stream to facilitate the use of message driven methods.

By using Spring Integration to connect the message broker middleware to realize message event driven.
Spring Cloud Stream provides personalized automatic configuration implementation for some vendors' message middleware products, citing the three core concepts of publish subscribe, consumption group and partition.

Currently, only RabbitMQ and Kafka are supported.

Official website Just click in and see for yourself Spring Cloud Stream Chinese instruction manual

Spring Cloud Stream is a highly scalable event driven microservice framework for building connections with shared messaging systems. The framework provides a flexible programming model based on established and familiar spring idioms and best practices, including three core concepts: publish / subscribe, consumer group and message partition

Spring Cloud Stream standard process routine

Case description

Message driven producer

Message driven consumers

Configure the cluster in the same group. Polling consumption is adopted by default

It's one for you, the next for him.

I still don't know much about many things in it.

What principle? I don't understand.

Group consumption and persistence

Let me talk about my understanding of this persistence, that is, when the receiver goes down and the information sent by the sender has not been consumed, it is still stored on rabbitMQ. When the receiver restarts the service, it can continue to consume the information.

Why can we consume those configured with grouping and not those without configuration?

06. SpringCloud Sleuth

  • Distributed request link tracking

summary

In the microservice framework, a request initiated by the client will be called by multiple different service nodes in the back-end system to produce the final request result. Each previous request will form a complex distributed service call link. The high delay or error of any link in the link will cause the final failure of the whole request.

Official website

Spring Cloud Sleuth provides a complete set of service tracking solutions

It provides tracking solutions in distributed systems and supports zipkin

Link monitoring steps

Complete link call

Represents a request link. A link is uniquely identified by Trace Id, span identifies the request information initiated, and each span is associated by parent id

Trace: a Span set similar to a tree structure, which represents a call link with unique identification

Span: refers to the source of the calling link. Generally speaking, span is a request for information

It provides personalized automatic configuration implementation * *, and refers to the three core concepts of publish subscribe, consumption group and partition.

Currently, only RabbitMQ and Kafka are supported.

Official website Just click in and see for yourself Spring Cloud Stream Chinese instruction manual

Spring Cloud Stream is a highly scalable event driven microservice framework for building connections with shared messaging systems. The framework provides a flexible programming model based on established and familiar spring idioms and best practices, including three core concepts: publish / subscribe, consumer group and message partition

[external chain picture transferring... (img-M7alrnAI-1646457403410)]

Spring Cloud Stream standard process routine

[external chain picture transferring... (img-4K6NTyeJ-1646457403411)]

[external chain picture transferring... (img-fDpUiX1h-1646457403412)]

[external chain picture transferring... (IMG lrucpvia-1646457403412)]

Case description

Message driven producer

Message driven consumers

Configure the cluster in the same group. Polling consumption is adopted by default

It's one for you, the next for him.

I still don't know much about many things in it.

What principle? I don't understand.

Group consumption and persistence

Let me talk about my understanding of this persistence, that is, when the receiver goes down and the information sent by the sender has not been consumed, it is still stored on rabbitMQ. When the receiver restarts the service, it can continue to consume the information.

Why can we consume those configured with grouping and not those without configuration?

06. SpringCloud Sleuth

  • Distributed request link tracking

summary

In the microservice framework, a request initiated by the client will be called by multiple different service nodes in the back-end system to produce the final request result. Each previous request will form a complex distributed service call link. The high delay or error of any link in the link will cause the final failure of the whole request.

[external chain picture transferring... (img-0D2dh996-1646457403413)]

[external chain picture transferring... (img-nid1aViq-1646457403413)]

Official website

Spring Cloud Sleuth provides a complete set of service tracking solutions

It provides tracking solutions in distributed systems and supports zipkin

[external chain picture transferring... (img-nd9cBE2A-1646457403414)]

Link monitoring steps

Complete link call

Represents a request link. A link is uniquely identified by Trace Id, span identifies the request information initiated, and each span is associated by parent id

[external chain picture transferring... (img-cffvJ9bY-1646457403414)]

[external chain picture transferring... (img-40z5vZJH-1646457403415)]

Trace: a Span set similar to a tree structure, which represents a call link with unique identification

Span: refers to the source of the calling link. Generally speaking, span is a request for information

Keywords: Java MySQL Spring Boot Microservices

Added by BrandonE97 on Sat, 05 Mar 2022 09:21:08 +0200