searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Hystrix简介

2024-01-02 02:13:55
27
0

背景&问题

微服务中的容错场景

  • 当链路上有节点无法正常提供服务无法立即响应请求时,请求会逐步积压在上层服务,逐步打挂整个链路上的服务,就像异常雪崩一样,从一点开始引起全局的一场大崩溃

解决方案

思路-熔断器

熔断器(Circuit Breaker)一词来源物理学中的电路知识,它的作用是当线路出现故障时,迅速切断电源以保护电路的安全。

在微服务领域,熔断器最早是由 Martin Fowler 在他发表的 一文中提出《Circuit Breaker》。与物理学中的熔断器作用相似,微服务架构中的熔断器能够在某个服务发生故障后,向服务调用方返回一个符合预期的、可处理的降级响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常。这样就保证了服务调用方的线程不会被长时间、不必要地占用,避免故障在微服务系统中的蔓延,防止系统雪崩效应的发生。

hystrix

简介

  • 目标
    • Hystrix: Latency and Fault Tolerance for Distributed Systems
    • 定位是一个解决分布式场景下,服务延迟和失败的容错性等问题
    • Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.
  • 项目状态
    • Hystrix is no longer in active development, and is currently in maintenance mode.
    • Hystrix (at version 1.5.18) is stable enough to meet the needs of Netflix for our existing applications.

重要特性

依赖隔离(预防阶段)
  • 目标
    • 某一个服务调用依赖A B两个服务,如果这时我有100个线程可用,我给A服务分配50个,给B服务分配50个,这样就算A服务挂了,我的B服务依然可以用。
  • 实现
    • 采用舱壁模式,在Hystrix中, 主要通过线程池来实现资源隔离.
    • 通常在使用的时候我们会根据调用的远程服务划分出多个线程池.
请求熔断(错误发生阶段)
  • 目标
    • Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力.
  • 打开断路器
    • 当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open).
    • 这时所有请求会直接失败而不会发送到后端服务.
  • 半打开
    • 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN).
  • 关闭断路器
    • 半打开状态下,这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回关闭状态(CLOSED), 否则重新切换到开路状态(OPEN).
服务降级(发生后处理)
  • Fallback相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值.

 

Hystrix实现

总流程图

Hystrix流程说明:

  • 1:每次调用创建一个新的HystrixCommand,把依赖调用封装在run()方法中.
  • 2:执行execute()/queue做同步或异步调用.
  • 3:判断熔断器(circuit-breaker)是否打开,如果打开跳到步骤8,进行降级策略,如果 关闭进入步骤.
  • 4:判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8,否则继续后续骤.
  • 5:调用HystrixCommand的run方法.运行依赖逻辑
    • 5a:依赖逻辑调用超时,进入步骤8.
  • 6:判断逻辑是否调用成功
    • 6a:返回成功调用结果
    • 6b:调用出错,进入步骤8.
  • 7:计算熔断器状态,所有的运行状态(成功, 失败, 拒绝,超时)上报给熔断器,用于统计从而判断熔断器状态.
  • 8:getFallback()降级逻辑.以下四种情况将触发getFallback调用:
    • (1):run()方法抛出非HystrixBadRequestException异常。
    • (2):run()方法调用超时
    • (3):熔断器开启拦截调用
    • (4):线程池/队列/信号量是否跑满
    • 8a:没有实现getFallback的Command将直接抛出异常
    • 8b:fallback降级逻辑调用成功直接返回
    • 8c:降级逻辑调用失败抛出异常
  • 9:返回执行成功结果

 

快速开始demo

demo-统计20秒内,10个请求有70%超时,则熔断
import com.netflix.hystrix.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/hystrix")
public class HystrixDemoController {

    /**
     * 模拟超时场景
     * @return
     * @throws Exception
     */
    @GetMapping("/timeout")
    public String timeout() throws Exception{
        // 20秒内,10个请求有70%超时,则熔断
        // 模拟调用15个请求,按理说调用到第11个请求(接收10个请求后,统计出70%超时)的时候,应该熔断,返回fallback结果
        for(int i=0; i<15; i++ ) {
            // 执行command
            try {
                RemoteCallTimeoutService remoteCallTimeoutService = new RemoteCallTimeoutService();
                System.out.println(i+"-"+remoteCallTimeoutService.execute());
            } catch (Exception e) {
                System.out.println(i+"-"+e.getMessage());
                if(i == 5 || i == 10){
                    Thread.sleep(1000);
                    commandStatus();
                }
            }
        }
        return "done";
    }

    /**
     * 获取Hystrix的监控信息
     * @return
     */
    @GetMapping("/commandStatus")
    public String commandStatus(){
        HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("DemoGroup");
        HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("RemoteCallTimeout");
        HystrixCircuitBreaker breaker = HystrixCircuitBreaker.Factory.getInstance(commandKey);
        HystrixCommandMetrics metrics = HystrixCommandMetrics.getInstance(commandKey);
        System.out.println("commandStatus=========================start");
        System.out.println("breaker.isOpen()=" + breaker.isOpen());
        System.out.println("metrics.getCommandGroup()=" + metrics.getCommandGroup());
        System.out.println("metrics.getCommandKey()=" + metrics.getCommandKey());
        System.out.println("metrics.getProperties().circuitBreakerEnabled()=" + metrics.getProperties().circuitBreakerEnabled().get());
        System.out.println("metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds())=" + metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds().get());
        System.out.println("metrics.getProperties().circuitBreakerRequestVolumeThreshold()=" + metrics.getProperties().circuitBreakerRequestVolumeThreshold().get());
        System.out.println("metrics.getProperties().circuitBreakerErrorThresholdPercentage()=" + metrics.getProperties().circuitBreakerErrorThresholdPercentage().get());
        System.out.println("metrics.getProperties().executionTimeoutInMilliseconds()=" + metrics.getProperties().executionTimeoutInMilliseconds().get());
        //Retrieve a snapshot of total requests, error count and error percentage.
        System.out.println("metrics.getHealthCounts()=total requests, error count and error percentage " + metrics.getHealthCounts());
        System.out.println("commandStatus=========================end");
        return "done";
    }

    /**
     * 20秒内,10个请求有70%超时,则熔断
     */
    private class RemoteCallTimeoutService extends HystrixCommand<String>{
        protected RemoteCallTimeoutService() {
            //super(HystrixCommandGroupKey.Factory.asKey("DemoGroup"), 5000);
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("DemoGroup"))
                    .andCommandKey(HystrixCommandKey.Factory.asKey("RemoteCallTimeout"))
                    .andCommandPropertiesDefaults(HystrixCommandProperties.defaultSetter()
                            .withCircuitBreakerEnabled(true)
                            .withMetricsRollingStatisticalWindowInMilliseconds(20000)   //统计最近20s内的数据
                            .withCircuitBreakerRequestVolumeThreshold(10)   //最少10个请求才开始计算是否熔断
                            .withCircuitBreakerErrorThresholdPercentage(70) //错误率70%则熔断
                            .withExecutionTimeoutInMilliseconds(1000)   //设置1秒超时
                    ));
        }
        @Override
        protected String run() throws Exception {
            // a real example would do work like a network call here
            Thread.sleep(1200); //模拟执行远程调用超时
            return "run return";
            //throw new Exception("invoke error"); //模拟执行远程调用抛异常
        }

        /*@Override
        protected String getFallback() {
            return "invoke fallback method";
        }*/
    }
}


  • 执行超时场景/hystrix/timeout
  • 输出结果如下:
    • 调用每次都超时
    • 在第6次的时候打印断路器状态,发现是未打开
    • 在第11次的时候打印断路器状态,发现已打开
0-RemoteCallTimeout timed-out and no fallback available.
1-RemoteCallTimeout timed-out and no fallback available.
2-RemoteCallTimeout timed-out and no fallback available.
3-RemoteCallTimeout timed-out and no fallback available.
4-RemoteCallTimeout timed-out and no fallback available.
5-RemoteCallTimeout timed-out and no fallback available.
commandStatus=========================start
breaker.isOpen()=false
metrics.getCommandGroup()=DemoGroup
metrics.getCommandKey()=RemoteCallTimeout
metrics.getProperties().circuitBreakerEnabled()=true
metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds())=20000
metrics.getProperties().circuitBreakerRequestVolumeThreshold()=10
metrics.getProperties().circuitBreakerErrorThresholdPercentage()=70
metrics.getProperties().executionTimeoutInMilliseconds()=1000
metrics.getHealthCounts()=total requests, error count and error percentage HealthCounts[6 / 6 : 100%]
commandStatus=========================end
6-RemoteCallTimeout timed-out and no fallback available.
7-RemoteCallTimeout timed-out and no fallback available.
8-RemoteCallTimeout timed-out and no fallback available.
9-RemoteCallTimeout timed-out and no fallback available.
10-RemoteCallTimeout timed-out and no fallback available.
commandStatus=========================start
breaker.isOpen()=true
metrics.getCommandGroup()=DemoGroup
metrics.getCommandKey()=RemoteCallTimeout
metrics.getProperties().circuitBreakerEnabled()=true
metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds())=20000
metrics.getProperties().circuitBreakerRequestVolumeThreshold()=10
metrics.getProperties().circuitBreakerErrorThresholdPercentage()=70
metrics.getProperties().executionTimeoutInMilliseconds()=1000
metrics.getHealthCounts()=total requests, error count and error percentage HealthCounts[11 / 11 : 100%]
commandStatus=========================end
11-RemoteCallTimeout short-circuited and no fallback available.
12-RemoteCallTimeout short-circuited and no fallback available.
13-RemoteCallTimeout short-circuited and no fallback available.
14-RemoteCallTimeout short-circuited and no fallback available.

 

demo-统计20秒内,10个请求有70%报错,则熔断

参考上面的代码,修改下执行逻辑直接抛异常

        @Override
        protected String run() throws Exception {
            // a real example would do work like a network call here
            //Thread.sleep(1200); //模拟执行远程调用超时
            //return "run return";
            throw new Exception("invoke error"); //模拟执行远程调用抛异常
        }
  • 输出结果如下:
    • 调用每次都超时
    • 在第6次的时候打印断路器状态,发现是未打开
    • 在第11次的时候打印断路器状态,发现已打开
0-RemoteCallTimeout failed and no fallback available.
1-RemoteCallTimeout failed and no fallback available.
2-RemoteCallTimeout failed and no fallback available.
3-RemoteCallTimeout failed and no fallback available.
4-RemoteCallTimeout failed and no fallback available.
5-RemoteCallTimeout failed and no fallback available.
commandStatus=========================start
breaker.isOpen()=false
metrics.getCommandGroup()=DemoGroup
metrics.getCommandKey()=RemoteCallTimeout
metrics.getProperties().circuitBreakerEnabled()=true
metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds())=20000
metrics.getProperties().circuitBreakerRequestVolumeThreshold()=10
metrics.getProperties().circuitBreakerErrorThresholdPercentage()=70
metrics.getProperties().executionTimeoutInMilliseconds()=1000
metrics.getHealthCounts()=total requests, error count and error percentage HealthCounts[6 / 6 : 100%]
commandStatus=========================end
6-RemoteCallTimeout failed and no fallback available.
7-RemoteCallTimeout failed and no fallback available.
8-RemoteCallTimeout failed and no fallback available.
9-RemoteCallTimeout failed and no fallback available.
10-RemoteCallTimeout failed and no fallback available.
commandStatus=========================start
breaker.isOpen()=true
metrics.getCommandGroup()=DemoGroup
metrics.getCommandKey()=RemoteCallTimeout
metrics.getProperties().circuitBreakerEnabled()=true
metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds())=20000
metrics.getProperties().circuitBreakerRequestVolumeThreshold()=10
metrics.getProperties().circuitBreakerErrorThresholdPercentage()=70
metrics.getProperties().executionTimeoutInMilliseconds()=1000
metrics.getHealthCounts()=total requests, error count and error percentage HealthCounts[11 / 11 : 100%]
commandStatus=========================end
11-RemoteCallTimeout short-circuited and no fallback available.
12-RemoteCallTimeout short-circuited and no fallback available.
13-RemoteCallTimeout short-circuited and no fallback available.
14-RemoteCallTimeout short-circuited and no fallback available.
0条评论
作者已关闭评论
q****n
20文章数
0粉丝数
q****n
20 文章 | 0 粉丝
q****n
20文章数
0粉丝数
q****n
20 文章 | 0 粉丝
原创

Hystrix简介

2024-01-02 02:13:55
27
0

背景&问题

微服务中的容错场景

  • 当链路上有节点无法正常提供服务无法立即响应请求时,请求会逐步积压在上层服务,逐步打挂整个链路上的服务,就像异常雪崩一样,从一点开始引起全局的一场大崩溃

解决方案

思路-熔断器

熔断器(Circuit Breaker)一词来源物理学中的电路知识,它的作用是当线路出现故障时,迅速切断电源以保护电路的安全。

在微服务领域,熔断器最早是由 Martin Fowler 在他发表的 一文中提出《Circuit Breaker》。与物理学中的熔断器作用相似,微服务架构中的熔断器能够在某个服务发生故障后,向服务调用方返回一个符合预期的、可处理的降级响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常。这样就保证了服务调用方的线程不会被长时间、不必要地占用,避免故障在微服务系统中的蔓延,防止系统雪崩效应的发生。

hystrix

简介

  • 目标
    • Hystrix: Latency and Fault Tolerance for Distributed Systems
    • 定位是一个解决分布式场景下,服务延迟和失败的容错性等问题
    • Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.
  • 项目状态
    • Hystrix is no longer in active development, and is currently in maintenance mode.
    • Hystrix (at version 1.5.18) is stable enough to meet the needs of Netflix for our existing applications.

重要特性

依赖隔离(预防阶段)
  • 目标
    • 某一个服务调用依赖A B两个服务,如果这时我有100个线程可用,我给A服务分配50个,给B服务分配50个,这样就算A服务挂了,我的B服务依然可以用。
  • 实现
    • 采用舱壁模式,在Hystrix中, 主要通过线程池来实现资源隔离.
    • 通常在使用的时候我们会根据调用的远程服务划分出多个线程池.
请求熔断(错误发生阶段)
  • 目标
    • Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力.
  • 打开断路器
    • 当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open).
    • 这时所有请求会直接失败而不会发送到后端服务.
  • 半打开
    • 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN).
  • 关闭断路器
    • 半打开状态下,这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回关闭状态(CLOSED), 否则重新切换到开路状态(OPEN).
服务降级(发生后处理)
  • Fallback相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值.

 

Hystrix实现

总流程图

Hystrix流程说明:

  • 1:每次调用创建一个新的HystrixCommand,把依赖调用封装在run()方法中.
  • 2:执行execute()/queue做同步或异步调用.
  • 3:判断熔断器(circuit-breaker)是否打开,如果打开跳到步骤8,进行降级策略,如果 关闭进入步骤.
  • 4:判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8,否则继续后续骤.
  • 5:调用HystrixCommand的run方法.运行依赖逻辑
    • 5a:依赖逻辑调用超时,进入步骤8.
  • 6:判断逻辑是否调用成功
    • 6a:返回成功调用结果
    • 6b:调用出错,进入步骤8.
  • 7:计算熔断器状态,所有的运行状态(成功, 失败, 拒绝,超时)上报给熔断器,用于统计从而判断熔断器状态.
  • 8:getFallback()降级逻辑.以下四种情况将触发getFallback调用:
    • (1):run()方法抛出非HystrixBadRequestException异常。
    • (2):run()方法调用超时
    • (3):熔断器开启拦截调用
    • (4):线程池/队列/信号量是否跑满
    • 8a:没有实现getFallback的Command将直接抛出异常
    • 8b:fallback降级逻辑调用成功直接返回
    • 8c:降级逻辑调用失败抛出异常
  • 9:返回执行成功结果

 

快速开始demo

demo-统计20秒内,10个请求有70%超时,则熔断
import com.netflix.hystrix.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/hystrix")
public class HystrixDemoController {

    /**
     * 模拟超时场景
     * @return
     * @throws Exception
     */
    @GetMapping("/timeout")
    public String timeout() throws Exception{
        // 20秒内,10个请求有70%超时,则熔断
        // 模拟调用15个请求,按理说调用到第11个请求(接收10个请求后,统计出70%超时)的时候,应该熔断,返回fallback结果
        for(int i=0; i<15; i++ ) {
            // 执行command
            try {
                RemoteCallTimeoutService remoteCallTimeoutService = new RemoteCallTimeoutService();
                System.out.println(i+"-"+remoteCallTimeoutService.execute());
            } catch (Exception e) {
                System.out.println(i+"-"+e.getMessage());
                if(i == 5 || i == 10){
                    Thread.sleep(1000);
                    commandStatus();
                }
            }
        }
        return "done";
    }

    /**
     * 获取Hystrix的监控信息
     * @return
     */
    @GetMapping("/commandStatus")
    public String commandStatus(){
        HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("DemoGroup");
        HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("RemoteCallTimeout");
        HystrixCircuitBreaker breaker = HystrixCircuitBreaker.Factory.getInstance(commandKey);
        HystrixCommandMetrics metrics = HystrixCommandMetrics.getInstance(commandKey);
        System.out.println("commandStatus=========================start");
        System.out.println("breaker.isOpen()=" + breaker.isOpen());
        System.out.println("metrics.getCommandGroup()=" + metrics.getCommandGroup());
        System.out.println("metrics.getCommandKey()=" + metrics.getCommandKey());
        System.out.println("metrics.getProperties().circuitBreakerEnabled()=" + metrics.getProperties().circuitBreakerEnabled().get());
        System.out.println("metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds())=" + metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds().get());
        System.out.println("metrics.getProperties().circuitBreakerRequestVolumeThreshold()=" + metrics.getProperties().circuitBreakerRequestVolumeThreshold().get());
        System.out.println("metrics.getProperties().circuitBreakerErrorThresholdPercentage()=" + metrics.getProperties().circuitBreakerErrorThresholdPercentage().get());
        System.out.println("metrics.getProperties().executionTimeoutInMilliseconds()=" + metrics.getProperties().executionTimeoutInMilliseconds().get());
        //Retrieve a snapshot of total requests, error count and error percentage.
        System.out.println("metrics.getHealthCounts()=total requests, error count and error percentage " + metrics.getHealthCounts());
        System.out.println("commandStatus=========================end");
        return "done";
    }

    /**
     * 20秒内,10个请求有70%超时,则熔断
     */
    private class RemoteCallTimeoutService extends HystrixCommand<String>{
        protected RemoteCallTimeoutService() {
            //super(HystrixCommandGroupKey.Factory.asKey("DemoGroup"), 5000);
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("DemoGroup"))
                    .andCommandKey(HystrixCommandKey.Factory.asKey("RemoteCallTimeout"))
                    .andCommandPropertiesDefaults(HystrixCommandProperties.defaultSetter()
                            .withCircuitBreakerEnabled(true)
                            .withMetricsRollingStatisticalWindowInMilliseconds(20000)   //统计最近20s内的数据
                            .withCircuitBreakerRequestVolumeThreshold(10)   //最少10个请求才开始计算是否熔断
                            .withCircuitBreakerErrorThresholdPercentage(70) //错误率70%则熔断
                            .withExecutionTimeoutInMilliseconds(1000)   //设置1秒超时
                    ));
        }
        @Override
        protected String run() throws Exception {
            // a real example would do work like a network call here
            Thread.sleep(1200); //模拟执行远程调用超时
            return "run return";
            //throw new Exception("invoke error"); //模拟执行远程调用抛异常
        }

        /*@Override
        protected String getFallback() {
            return "invoke fallback method";
        }*/
    }
}


  • 执行超时场景/hystrix/timeout
  • 输出结果如下:
    • 调用每次都超时
    • 在第6次的时候打印断路器状态,发现是未打开
    • 在第11次的时候打印断路器状态,发现已打开
0-RemoteCallTimeout timed-out and no fallback available.
1-RemoteCallTimeout timed-out and no fallback available.
2-RemoteCallTimeout timed-out and no fallback available.
3-RemoteCallTimeout timed-out and no fallback available.
4-RemoteCallTimeout timed-out and no fallback available.
5-RemoteCallTimeout timed-out and no fallback available.
commandStatus=========================start
breaker.isOpen()=false
metrics.getCommandGroup()=DemoGroup
metrics.getCommandKey()=RemoteCallTimeout
metrics.getProperties().circuitBreakerEnabled()=true
metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds())=20000
metrics.getProperties().circuitBreakerRequestVolumeThreshold()=10
metrics.getProperties().circuitBreakerErrorThresholdPercentage()=70
metrics.getProperties().executionTimeoutInMilliseconds()=1000
metrics.getHealthCounts()=total requests, error count and error percentage HealthCounts[6 / 6 : 100%]
commandStatus=========================end
6-RemoteCallTimeout timed-out and no fallback available.
7-RemoteCallTimeout timed-out and no fallback available.
8-RemoteCallTimeout timed-out and no fallback available.
9-RemoteCallTimeout timed-out and no fallback available.
10-RemoteCallTimeout timed-out and no fallback available.
commandStatus=========================start
breaker.isOpen()=true
metrics.getCommandGroup()=DemoGroup
metrics.getCommandKey()=RemoteCallTimeout
metrics.getProperties().circuitBreakerEnabled()=true
metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds())=20000
metrics.getProperties().circuitBreakerRequestVolumeThreshold()=10
metrics.getProperties().circuitBreakerErrorThresholdPercentage()=70
metrics.getProperties().executionTimeoutInMilliseconds()=1000
metrics.getHealthCounts()=total requests, error count and error percentage HealthCounts[11 / 11 : 100%]
commandStatus=========================end
11-RemoteCallTimeout short-circuited and no fallback available.
12-RemoteCallTimeout short-circuited and no fallback available.
13-RemoteCallTimeout short-circuited and no fallback available.
14-RemoteCallTimeout short-circuited and no fallback available.

 

demo-统计20秒内,10个请求有70%报错,则熔断

参考上面的代码,修改下执行逻辑直接抛异常

        @Override
        protected String run() throws Exception {
            // a real example would do work like a network call here
            //Thread.sleep(1200); //模拟执行远程调用超时
            //return "run return";
            throw new Exception("invoke error"); //模拟执行远程调用抛异常
        }
  • 输出结果如下:
    • 调用每次都超时
    • 在第6次的时候打印断路器状态,发现是未打开
    • 在第11次的时候打印断路器状态,发现已打开
0-RemoteCallTimeout failed and no fallback available.
1-RemoteCallTimeout failed and no fallback available.
2-RemoteCallTimeout failed and no fallback available.
3-RemoteCallTimeout failed and no fallback available.
4-RemoteCallTimeout failed and no fallback available.
5-RemoteCallTimeout failed and no fallback available.
commandStatus=========================start
breaker.isOpen()=false
metrics.getCommandGroup()=DemoGroup
metrics.getCommandKey()=RemoteCallTimeout
metrics.getProperties().circuitBreakerEnabled()=true
metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds())=20000
metrics.getProperties().circuitBreakerRequestVolumeThreshold()=10
metrics.getProperties().circuitBreakerErrorThresholdPercentage()=70
metrics.getProperties().executionTimeoutInMilliseconds()=1000
metrics.getHealthCounts()=total requests, error count and error percentage HealthCounts[6 / 6 : 100%]
commandStatus=========================end
6-RemoteCallTimeout failed and no fallback available.
7-RemoteCallTimeout failed and no fallback available.
8-RemoteCallTimeout failed and no fallback available.
9-RemoteCallTimeout failed and no fallback available.
10-RemoteCallTimeout failed and no fallback available.
commandStatus=========================start
breaker.isOpen()=true
metrics.getCommandGroup()=DemoGroup
metrics.getCommandKey()=RemoteCallTimeout
metrics.getProperties().circuitBreakerEnabled()=true
metrics.getProperties().metricsRollingStatisticalWindowInMilliseconds())=20000
metrics.getProperties().circuitBreakerRequestVolumeThreshold()=10
metrics.getProperties().circuitBreakerErrorThresholdPercentage()=70
metrics.getProperties().executionTimeoutInMilliseconds()=1000
metrics.getHealthCounts()=total requests, error count and error percentage HealthCounts[11 / 11 : 100%]
commandStatus=========================end
11-RemoteCallTimeout short-circuited and no fallback available.
12-RemoteCallTimeout short-circuited and no fallback available.
13-RemoteCallTimeout short-circuited and no fallback available.
14-RemoteCallTimeout short-circuited and no fallback available.
文章来自个人专栏
云技术专栏
20 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0