A list,

  • Basic introduction

    In the microservice architecture, we divide the service into several units and call each other through remote services. If a node fails in the process of multi-stage node invocation, the failure will spread due to dependency, resulting in avalanche. In order to ensure the availability of the system, we propose a circuit breaker model. Netflix has open-source the Hystrix component, which uses Resilience4j (a lightweight, easy-to-use fault-tolerant library inspired by Netflix Hystrix but designed for Java8 and functional programming) in versions 2.4.x and up.

  • Why the break

    1. Isolation: Requests are encapsulated in HystrixCommand, and these requests are then executed in a separate thread. Each dependent service maintains a small thread pool (or semaphore) that can disconnect the dependent call or return the specified logic in case the call fails or times out
    2. Degradation: Service degradation is the value returned by the fallback method when an exception occurs on the request back-end service
    3. Fusing: When the number of HystrixCommand requests to the back-end service fails exceeds a certain percentage (50% by default), the circuit breaker switches to the Open state. After the circuit breaker remains OPEN for a period of time (5 seconds by default), it automatically switches to half-open. Then it determines the return status of the next request. If the request is successful, the circuit breaker switches back to the CLOSED state. Otherwise switch back to the OPEN state
    4. Dashboards: Hystrix provides visual dashboards for real-time monitoring of service availability
  • Hystrix process description

    1: create a new HystrixCommand for each call, encapsulating the dependent calls in the run() method. 2: execute()/queue for synchronous or asynchronous calls. 4: Check whether the circuit-breaker is open. If it is open, skip to Step 8 for downgrade strategy. If it is closed, go to Step 5. If the run is full, go to degraded step 8, otherwise proceed to step 6.6: call HystrixCommand’s run method. 7: Check whether the invocation of logic is successful. 7A: return the result of successful invocation. 7b: invoke error, enter Step 8.8. 9:getFallback() degradation logic. The following four conditions will trigger getFallback call: (1) : the run () method to throw a non HystrixBadRequestException anomalies. (2):run() method call timeout (3): fuse start interception call (4): thread pool/queue/semaphore run full 9c: the degraded logical invocation fails. 10: The execution result is successful

  • Opening strategy

    1. Active disconnection: When the client requests a timeout period, the timeout period is directly set to prevent service accumulation

    2. Traffic limiting: Set the maximum number of concurrent requests in high concurrency scenarios

    3. Degraded: Returns specified default information after a service failure or exception. This is usually handled on the server side

    4. Fusing: When the number of errors exceeds the threshold, the system fails quickly. The system does not call the back-end service and sends several requests to retry whether the back-end service can be invoked normally. If the backend service can be invoked successfully, the system shuts down the fusing state. (There is a retry, which is the ability to bounce back.)

    5. Isolation: Each dependent or invoked service is isolated to prevent cascading failures from making the entire service unavailable

Hystrix is used independently

  • Pom depends on

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <! -- Dashboard dependencies -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    <! -- Health Monitoring package -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    Copy the code
  • A launch configuration

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableCircuitBreaker// Start the circuit breaker
    @EnableHystrixDashboard// Open the dashboard
    public class BikeHystrixApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(BikeHystrixApplication.class, args);
        }
    
        /** * Set load balancing *@return* /
        @Bean
        @LoadBalanced
        RestTemplate restTemplate(a){
    
            return newRestTemplate(); }}Copy the code
  • The validation test

    1. Service degradation: A service disconnection policy that returns a default value when the service is unavailable.

      @RestController
      @RequestMapping("/bike-hystrix")
      @Slf4j
      public class BikeHystrixController {
      
          @Autowired
          RestTemplate restTemplate;
      
        	// Add an annotation to specify the callback method
          @HystrixCommand(fallbackMethod = "fallBack")
          @GetMapping("/hystrix")
          public String hystrix(a){
            	
            	// Simulate service exception, triggering service degradation
            	int i=1/0;
      
              String resp = null;
              /** * If restTemplate is not set@LoadBalancedIf this annotation is configured, use the service name */. If this annotation is configured, use the service name */
              resp = restTemplate.getForObject("http://bike-business/bike-business/hystrix", String.class);
      
              return resp;
      
          }
      
      		// This method is executed when the business method executes abnormally, which is equivalent to service degradation, which is often used on the server side. Returns a default value when the current service is unavailable
          public String fallBack(a){
              return "this is hystrix err "; }}Copy the code

      HystrixCommand notes

      @Target({ElementType.METHOD})
      @Retention(RetentionPolicy.RUNTIME)
      @Inherited
      @Documented
      public @interface HystrixCommand {
           // HystrixCommand Name of the group to which the command belongs: name of the default annotation method class
          String groupKey(a) default "";
       
          HystrixCommand Specifies the key value of the command. The default value is the name of the annotation method
          String commandKey(a) default "";
       
          // Thread pool name, defined by default as groupKey
          String threadPoolKey(a) default "";
          // Define the name of the fallback method, which must be in the same class as the hystrix execution method
          String fallbackMethod(a) default "";
          // Set parameters of the hystrix command
          HystrixProperty[] commandProperties() default {};
          // Set the parameters of the thread pool on which Hystrix depends
          HystrixProperty[] threadPoolProperties() default {};
       
          // If the hystrix method throws an exception that includes RUNTIME_EXCEPTION, HystrixRuntimeException will be wrapped. We can also use this method to define which exceptions to ignore
          Class<? extends Throwable>[] ignoreExceptions() default {};
       
          ObservableExecutionMode specifies the ObservableExecutionMode for executing hystrix Observable commands
          ObservableExecutionMode observableExecutionMode(a) default ObservableExecutionMode.EAGER;
       
          // If the hystrix method throws an exception that includes RUNTIME_EXCEPTION, HystrixRuntimeException will be wrapped. This method defines the exception that needs to be thrown
          HystrixException[] raiseHystrixExceptions() default {};
       
          // Define callback methods: defaultFallback cannot pass in arguments, however. The returned arguments are compatible with hystrix commands
          String defaultFallback(a) default "";
      }
      Copy the code
    2. Service fusing

      • To test service fusing, we need to open multiple service nodes for verification, respectively open bike-Business and bike-business2 business systems and add the same interface

        @GetMapping("/hystrix")
        public String hystrix(a){
            return "hystrix resp : " + port;
        }
        Copy the code
      • Hystrix timeout is added to the client. The timeout is set to 2 seconds. In the previous step, the Bike-Business2 system is shut down to simulate server downtime. So we can expect, when bike-business2 fuse, the result will only return the result of bike-business

        hystrix:
          command:
            default:
              execution:
                isolation:
                  strategy: SEMAPHORE
                  thread:
                    timeoutInMilliseconds: 2000 # Set hystrix timeout to 2s
        Copy the code
      • A postman mock request to view the log print will then return only bike-business results after a fallback is triggered multiple times

        c.b.h.controller.BikeHystrixController   : this is hystrix err 
        c.b.h.controller.BikeHystrixController   : hystrix resp : 8126
        c.b.h.controller.BikeHystrixController   : hystrix resp : 8126
        c.b.h.controller.BikeHystrixController   : hystrix resp : 8126
        c.b.h.controller.BikeHystrixController   : hystrix resp : 8126
        c.b.h.controller.BikeHystrixController   : hystrix resp : 8126
        c.b.h.controller.BikeHystrixController   : hystrix resp : 8126
        Copy the code

3. OpenFeign integration

  • Pom depends on

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    Copy the code
  • A launch configuration

    @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
    @EnableDiscoveryClient
    @EnableCircuitBreaker
    @EnableHystrixDashboard
    @EnableFeignClients/ / open feign
    public class BikeHystrixApplication {
    
        public static void main(String[] args) { SpringApplication.run(BikeHystrixApplication.class, args); }}Copy the code
  • The configuration file

    feign:
      hystrix:
        enabled: true # Enable fuse breaker support
    Copy the code
  • The validation test

    1. Configuration feignClient

      // Specify the service degraded class by configuring fallbackFactory
      @FeignClient(value = "bike-business",fallbackFactory = FallbackFactory.class)
      public interface BikeHystrixFeignClient {
      
          @GetMapping("/bike-business/hystrix")
          String hystrix(a);
      }
      Copy the code
    2. Service degradation realized

      /** * implements the FallbackFactory interface */
      @Component
      @Slf4j
      public class FallbackFactory implements feign.hystrix.FallbackFactory<BikeHystrixFeignClient> {
      
          @Override
          public BikeHystrixFeignClient create(Throwable throwable) {
              log.error(throwable.getMessage());
            	// Customize the return data of the exception case through an anonymous inner class
              return new BikeHystrixFeignClient(){
                  @Override
                  public String hystrix(a) {
                      returnthrowable.getMessage(); }}; }}Copy the code
    3. The validation test

      Feign call interface is added in controller. During the verification process, if a node of bike-Business service stops, Feign will perform single-node fuse. When the service restarts, the service will be automatically distributed to the restarted node. Trigger FallbackFactory implementation when all bike-business node services are unavailable.

Four, instrument panel

  • Pom depends on

    <! -- New dashboard dependencies -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    Copy the code
  • A launch configuration

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableCircuitBreaker// Start the circuit breaker
    @EnableHystrixDashboard// Open the dashboard
    public class BikeHystrixApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(BikeHystrixApplication.class, args);
        }
    
        /** * Set load balancing *@return* /
        @Bean
        @LoadBalanced
        RestTemplate restTemplate(a){
    
            return newRestTemplate(); }}Copy the code
  • The configuration file

    hystrix:
      command:
        default:
          execution:
            timeout:
              # Whether to enable the timeout circuit breaker
              enabled: true
            isolation:
            	# Hystrix Isolation policy
            	#SEMAPHORE - It is executed on the calling thread and concurrent requests are limited by SEMAPHORE counts (Zuul defaults to this policy)
    					#THREAD - This executes on a single THREAD, and concurrent requests are limited by the number of threads in the THREAD pool
              strategy: SEMAPHORE If Thread Pools in the dashboard are in loading state, Therad isolation policy can be set
              thread:
                timeoutInMilliseconds: 2000 # Set hystrix timeout to 2s
      Add local proxy list
      dashboard:
        proxy-stream-allow-list: "localhost"
    
    Expose all surveillance information
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    Copy the code
  • The validation test

    1. Start the project, visit http://localhost:8128/hystrix

    • Deplay This parameter controls the delay of polling monitoring information on the server. The default value is 2000 milliseconds. You can configure this parameter to reduce the network and CPU consumption of the client.
    • Title This parameter corresponds to the content after the header Title Hystrix Stream. By default, the URL of the specific monitoring instance is used. If possible, you can configure this information to display a more appropriate Title.
    1. According to the Hystrix Dashboard tips to fill in the specific monitoring service, such as Single Single node Hystrix App fill in https://hystrix-app:port/actuator/hystrix.stream

    2. Viewing Monitoring Parameters

      • Solid circle: Has two meanings. It represents the health degree of the instance by color change, and its health degree decreases from green > yellow > orange > red. Its size will also change according to the request traffic of instances. The larger the traffic, the larger the solid circle will be. Therefore, through the display of the solid circle, fault instances and high pressure instances can be quickly found in a large number of instances
      • Percentage: percentage of errors within the last 10 seconds
      • Circuit: indicates the state of being disconnected
    3. Simulation of fusing

      • Stop all nodes of the remote service bike-business, and then frequently request the remote service through Feign to observe the status changes of the dashboard

      • Postman returns Hystrix circuit short-circuited and is OPEN.

      Source address: source address