SpringCloud-Hystrix service downgrade and circuit breaker

Please see gitee for the entire project: https://gitee.com/xwb1056481167/spring-cloud

Hystrix

  • Hystrix is ​​an open source library used to deal with the delay and fault tolerance of distributed systems. In distributed systems, many rely on inevitable call failures, such as timeouts, exceptions, and so on. Hystrix can ensure that in the case of a dependency problem, the overall service will not fail, avoid cascading failures, and improve the resilience of the distributed system
  • The "circuit breaker" itself is a kind of switching device. When a service unit fails, the fault monitoring of the circuit breaker (similar to a blown fuse)  will return an expected and handleable alternative response (FallBack) to the calling method. Rather than waiting for a long time or throwing exceptions for calling the method ,  this ensures that the service caller's thread will not be occupied for a long time and unnecessary, thus avoiding the spread of faults in the distributed system, and even an avalanche.

For more detailed instructions on fuse downgrade, please go to:  https://blog.csdn.net/www1056481167/article/details/81157171 View

Service degradation

The service provider cloud-provider-hystrix-payment8001 downgrade
the service consumer cloud-provider-hystrix-payment80 downgrade

Service provider cloud-provider-hystrix-payment8001's own service is downgraded

1 、 pom.xml

<!-- hystrix -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2. The main startup class @EnableCircuitBreaker

@SpringBootApplication
@EnableDiscoveryClient //服务发现
@EnableCircuitBreaker //开启断路器功能
public class PaymentHystrixMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentHystrixMain8001.class, args);
    }
}

3. Service method to downgrade service

 //执行方法时抛异常 执行fallbackMethod里面的方法,并且由HystrixProperty指定等待时长
 @HystrixCommand(fallbackMethod = "paymentInfo_timeOutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public String paymentInfo_timeOut(Integer id) {
        try {
            //int age = 10 / 0;
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池: " + Thread.currentThread().getName() + "  paymentInfo_TineOut,id: " + id + "\\t" + ")(哈哈)";
    }
    public String paymentInfo_timeOutHandler(Integer id) {
        return "线程池: " + Thread.currentThread().getName() + "  系统繁忙,请稍后重试 id: " + id + "\\t" + ")";
    }

Test result: only 7001,8001 services started

Service consumer cloud-provider-hystrix-payment80's own service downgrade

1. Provide downgraded hystrix dependency packages

<!-- hystrix -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2. yml's service is downgraded and turned on

feign:
  hystrix:
    #开启feign的hystrix支持,默认是false    
    enabled: true

3. Add @EnableHystrix to the main startup class

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //开启负载均衡
@EnableHystrix //开启服务熔断
public class OrderHystrixMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderHystrixMain80.class, args);
    }
}

4. Perform downgrade processing on the interface that needs service downgrade (here is the operation under the OrderHystrixController class under the controller)

@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod", commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
})
public String paymentFeignTimeOut(@PathVariable("id") Integer id) {
    return paymentHystrixService.paymentInfo_timeOut(id);
}

public String paymentTimeOutFallbackMethod(Integer id) {
    return "我是消费者80,调用hystrix8001系统繁忙,请稍后重试,或者运行就自己的出错检查";
}

Processing result (test result: only start 7001,8001,80)

Global unified service downgrade @DefaultProperties(defaultFallback="")

DefaultProperties(defaultFallback="")  N multiple methods, except for individual core businesses that are exclusive, all others can use @DefaultProperties(defaultFallback="")

The last chapter talked about downgrading the service. If each method is configured with a fallBackMethod on time, the code will be very bloated. So we use DefaultProperties(defaultFallback="")

Provide global exception information summary class

/**
 * 本方法提供类hystrix的统一熔断方法集合<br/>
 * 需要其他controller继承,然后根据方法的定义返回统一的,或者是单独自定义的异常熔断信息返回即可
 */
public class BaseHystrix {
    //以下是全局fallback方法
    public String payment_global_fallbackMethod() {
        return "Global 异常异常处理信息,请稍后重试";
    }
    public String paymentTimeOutFallbackMethod(Integer id) {
        return "我是消费者80,调用hystrix8001系统繁忙,请稍后重试,或者运行就自己的出错检查";
    }
}

1. Perform unified service downgrade processing on the controller

@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_global_fallbackMethod")
public class OrderHystrixController extends BaseHystrix {
    @Resource
    private PaymentHystrixService paymentHystrixService;

    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
    })
    //@HystrixCommand
    public String paymentFeignTimeOut(@PathVariable("id") Integer id) {
        int a=10/0;
        return paymentHystrixService.paymentInfo_timeOut(id);
    }
}

Description: Perform service downgrade processing for the entire controller @DefaultProperties(defaultFallback="payment_global_fallbackMethod") Provide a unified downgrade processing DefaultProperties and specify the method as payment_global_fallbackMethod.

1. First add the annotation @DefaultProperties(defaultFallback="") on the controller, and then specify the globally unified service downgrade method as payment_global_fallbackMethod
2. Downgrade the service of the method

2.1. Only the @HystrixCommand annotation is added above the method, which means that if the execution of this interface fails, the global unified service degradation will be performed.

@GetMapping("/consumer/payment/hystrix/timeout/{id}")
 @HystrixCommand
 public String paymentFeignTimeOut(@PathVariable("id") Integer id) {
     int a=10/0;
 }

2.2. If @HystrixCommand is added to the method and fallbackMethod is specified, it indicates that the specified method will be executed when the service is degraded.

@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod", commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
})
public String paymentFeignTimeOut(@PathVariable("id") Integer id) {
    int a=10/0;
}

2.3. If @HystrixCommand is not added to the method, it means that the method does not perform service degradation. If an exception occurs, the error message will be directly thrown to the client. Very unfriendly.

@GetMapping("/consumer/payment/hystrix/timeout/{id}")
public String paymentFeignTimeOut(@PathVariable("id") Integer id) {
    int a=10/0;
}

Directory Structure 

Service fusing

The concept of fuse mechanism The fuse mechanism is a microservice link protection mechanism to deal with the avalanche effect. When a certain microservice of the deleted link is unavailable or the response time is too long, the service will be degraded and the node will be fuse. Service call, quickly return wrong response information

Service degradation -> then fuse -> reply to the call link

When it is detected that the service street store microservice call response is normal, the call link is restored

In the SpringCloud framework, the fuse mechanism is implemented by Hystrix. Hystrix will monitor the status of calls between microservices. When the failed calls reach a certain threshold, the default is 5 seconds and 20 calls fail, and the fuse mechanism will be activated. The annotation of the fuse mechanism is @HystrixCommand.

The Command property is mainly used to control the behavior of the HystrixCommand command. It is mainly divided into the following categories. For more configurations, please see the category: com.netflix.hystrix.HystrixCommandProperties

1 Execution: used to control the execution of HystrixCommand.run()


execution.isolation.strategy:该属性用来设置HystrixCommand.run()执行的隔离策略。默认为THREAD。
execution.isolation.thread.timeoutInMilliseconds:该属性用来配置HystrixCommand执行的超时时间,单位为毫秒。
execution.timeout.enabled:该属性用来配置HystrixCommand.run()的执行是否启用超时时间。默认为true。
execution.isolation.thread.interruptOnTimeout:该属性用来配置当HystrixCommand.run()执行超时的时候是否要它中断。
execution.isolation.thread.interruptOnCancel:该属性用来配置当HystrixCommand.run()执行取消时是否要它中断。
execution.isolation.semaphore.maxConcurrentRequests:当HystrixCommand命令的隔离策略使用信号量时,该属性用来配置信号量的大小。当最大并发请求达到该设置值时,后续的请求将被拒绝。

2 Fallback: used to control the execution of HystrixCommand.getFallback()


fallback.isolation.semaphore.maxConcurrentRequests:该属性用来设置从调用线程中允许HystrixCommand.getFallback()方法执行的最大并发请求数。当达到最大并发请求时,后续的请求将会被拒绝并抛出异常。
fallback.enabled:该属性用来设置服务降级策略是否启用,默认是true。如果设置为false,当请求失败或者拒绝发生时,将不会调用HystrixCommand.getFallback()来执行服务降级逻辑。

3 Circuit Breaker: Used to control the behavior of HystrixCircuitBreaker.

 circuitBreaker.enabled:确定当服务请求命令失败时,是否使用断路器来跟踪其健康指标和熔断请求。默认为true。
 circuitBreaker.requestVolumeThreshold:用来设置在滚动时间窗中,断路器熔断的最小请求数。例如,默认该值为20的时候,如果滚动时间窗(默认10秒)内仅收到19个请求,即使这19个请求都失败了,断路器也不会打开。
 circuitBreaker.sleepWindowInMilliseconds:用来设置当断路器打开之后的休眠时间窗。休眠时间窗结束之后,会将断路器设置为“半开”状态,尝试熔断的请求命令,如果依然时候就将断路器继续设置为“打开”状态,如果成功,就设置为“关闭”状态。
 circuitBreaker.errorThresholdPercentage:该属性用来设置断路器打开的错误百分比条件。默认值为50,表示在滚动时间窗中,在请求值超过requestVolumeThreshold阈值的前提下,如果错误请求数百分比超过50,就把断路器设置为“打开”状态,否则就设置为“关闭”状态。
 circuitBreaker.forceOpen:该属性默认为false。如果该属性设置为true,断路器将强制进入“打开”状态,它会拒绝所有请求。该属性优于forceClosed属性。
 circuitBreaker.forceClosed:该属性默认为false。如果该属性设置为true,断路器强制进入“关闭”状态,它会接收所有请求。如果forceOpen属性为true,该属性不生效。

4 Metrics: This attribute is related to the metrics captured by HystrixCommand and HystrixObservableCommand.

metrics.rollingStats.timeInMilliseconds:该属性用来设置滚动时间窗的长度,单位为毫秒。该时间用于断路器判断健康度时需要收集信息的持续时间。断路器在收集指标信息时会根据设置的时间窗长度拆分成多个桶来累计各度量值,每个桶记录了一段时间的采集指标。例如,当为默认值10000毫秒时,断路器默认将其分成10个桶,每个桶记录1000毫秒内的指标信息。
metrics.rollingStats.numBuckets:用来设置滚动时间窗统计指标信息时划分“桶”的数量。默认值为10。
metrics.rollingPercentile.enabled:用来设置对命令执行延迟是否使用百分位数来跟踪和计算。默认为true,如果设置为false,那么所有的概要统计都将返回-1。
metrics.rollingPercentile.timeInMilliseconds:用来设置百分位统计的滚动窗口的持续时间,单位为毫秒。
metrics.rollingPercentile.numBuckets:用来设置百分位统计滚动窗口中使用桶的数量。
metrics.rollingPercentile.bucketSize:用来设置每个“桶”中保留的最大执行数。
metrics.healthSnapshot.intervalInMilliseconds:用来设置采集影响断路器状态的健康快照的间隔等待时间。

5 Request Context: It involves the setting of HystrixCommand using HystrixRequestContext.

requestCache.enabled:用来配置是否开启请求缓存。
requestLog.enabled:用来设置HystrixCommand的执行和事件是否打印到日志的HystrixRequestLog中。

Use cloud-provider-hystrix-payment8001 in the project

1. Introduce jar

<!-- hystrix -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2. Modify the service method

@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = {
       @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //是否开启断路器
       @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //请求次数
       @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //时间窗口期
       @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), //失败率到达多少后跳闸
})
public String paymentCircuitBreaker(@PathVariable("id") Integer id) {
   if (id > 0) {
       throw new RuntimeException("*************** id 不能为负数");
   }
   String serialNumber = IdUtil.simpleUUID();
   return Thread.currentThread().getName() + "\\t" + "调用成功,流水号为: " + serialNumber;
}

public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id) {
   return "id 不能为负数,请稍后重试, id:" + id;
}

3. Controller call

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

Call result:

Principle analysis

From 1->3 above, it can be seen that the core idea of service fuse is service degradation -> and then fuse -> reply to the call link

1. When there is a request to call, it will not call the main logic, but directly call the fallback of the service degradation. Through the circuit breaker, the error is automatically found and the degradation logic is switched to the main logic, which reduces the corresponding delay. .
2. How to restore the original logic.  
    For this problem, hystrix has also realized the automatic recovery function for us.  
    When the circuit breaker is opened and the main logic is blown, hystrix will start a sleep time window. During this time window, the degraded logic is a snack to become the main logic.  
    When the sleep time window expires, the circuit breaker will enter a half-open state. Release a request to the original main logic. If the request returns normally, the circuit breaker will continue to close and the  
    main logic resumes. If there is still a problem with this request, the circuit breaker will continue to enter the open state, and the sleep time window will be timed again. .  

Guess you like

Origin blog.csdn.net/www1056481167/article/details/113768408