Hystrix熔断监控接入

569 阅读3分钟

一、实践涉及的内容

  1. 创建一个springboot的hystrix工程
  2. 创建一个command模拟调用三方接口,模拟出现是失败、超时等情况
  3. springboot中引入hystrix的stream模块,用于发送hystrix中的command、threadpool的当前的状态给dashboard,例如失败数、超时数、活跃线程、等待队列大小、断路器开关等信息
  4. 启动dashboard,监控springboot工程的command状况
  5. 通过调节一些hystrix参数(熔断策略),从监控观察熔断状态

二、hystrix工程创建

1、hystrix核心模块

1.1 通过spring的starter创建springboot工程

创建spring时添加Spring web的依赖

1.2 引入hystrix相关依赖

<!-- hystrix的核心包 -->
<dependency>
	<groupId>com.netflix.hystrix</groupId>
	<artifactId>hystrix-core</artifactId>
	<version>1.5.18</version>
</dependency>

1.3 创建HystrixCommand

  1. 用failRate、timeoutRate来模拟失败和超时的比例
  2. 通过随机数+sleep完成一个简单的模拟调用三方接口的目标
/**
 *
 * failRate表示失败比例,最多两位小数
 * timeoutRate表示超时比例,最多两位小数(默认超时时间是1秒,这里休眠2秒,模拟超时)
 * 成功的比例为1-failRate-timeoutRate
 *
 * name表示hystrixCommand的名称
 *
 */
public class HystrixCommandDemo extends HystrixCommand<String> {

    private static final int HIGH = 10000;
    private String name;
    private double failRate;
    private double timeoutRate;

    public HystrixCommandDemo(String name, String groupName, double failRate, double timeoutRate) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupName))
                .andCommandKey(HystrixCommandKey.Factory.asKey(name)));
        this.name = name;
        if (failRate + timeoutRate >= 1) {
            throw new RuntimeException("总比例不能超过1");
        }
        this.failRate = failRate;
        this.timeoutRate = timeoutRate;
    }

    @Override
    protected String run() throws Exception {

        /**
         * 随机生成一个0~9999的随机数,判断是否在failRate、timeoutRate的区间
         * 例如failRate:0.3, timeoutRate:0.4,那么也就是0~2999属于fail,3000~6999属于超时,其他是正常
         */
        Random random = new Random();
        int index = random.nextInt(HIGH);
        if (index < HIGH * failRate) {
            throw new RuntimeException("run time exception");
        } else if (index < HIGH * (failRate + timeoutRate)) {
            System.out.println("timeout");
            Thread.sleep(2000);
        }

        // 正常请求耗时500毫秒
        Thread.sleep(500);

        return "hello:" + name;
    }

    @Override
    protected String getFallback() {
        return "fallback";
    }
}

1.4 service&controller

实现过于简单,就不做详细介绍

@Service
public class HystrixService {

    public String run(double failRate, double timeoutRate, String name, String groupName) {
        HystrixCommandDemo demoCommand = new HystrixCommandDemo(name, groupName, failRate, timeoutRate);
        String execute = demoCommand.execute();
        System.out.println(execute);

        return execute;
    }
}

@RestController
@RequestMapping("/")
public class HystrixController {
    @Autowired
    private HystrixService hystrixService;

    @GetMapping("run")
    public String runHystrix(@RequestParam("failRate")double failRate,
                             @RequestParam("timeoutRate")double timeoutRate) {
        // 同一个group 多command
        hystrixService.run(failRate, timeoutRate, "getAllData", "getDataGroup");
        hystrixService.run(failRate, timeoutRate, "getData", "getDataGroup");

        return "success";
    }

    @GetMapping("do")
    public String doHystrix(@RequestParam("failRate")double failRate,
                             @RequestParam("timeoutRate")double timeoutRate) {
        return hystrixService.run(failRate, timeoutRate, "updateData", "updateDataGroup");
    }
}

2、hystrix的event-stream模块

参考hystrix简介中的dashboard模块的文档

2.1 stream依赖导入

<!-- hystrix用来向dashboard发送数据的依赖 -->
<dependency>
	<groupId>com.netflix.hystrix</groupId>
	<artifactId>hystrix-metrics-event-stream</artifactId>
	<version>1.4.10</version>
</dependency>

2.2 创建servlet

创建servlet,用来发送command状态数据

@Configuration
public class HystrixConfiguration {

    @Bean
    public ServletRegistrationBean getStreamServlet() {
        ServletRegistrationBean servletRegistrationBean =
                new ServletRegistrationBean(new HystrixMetricsStreamServlet(), "/hystrix.stream");

        return servletRegistrationBean;
    }
}

3、启动hystrix

直接使用springboot启动类启动即可

3.1 测试rest url是否能访问通

返回success就表示成功

curl http://localhost:9990/run?failRate=0.2&timeoutRate=0.2

3.2 测试hystrix.stream是否能正常发送数据

  1. 成功会返回类似:data: {"type":"HystrixCommand","name":"getData"....}
  2. 具体发送数据这里不做解析,放在后面源码解析部分
curl http://localhost:9990/hystrix.stream

三、hystrix之dashboard

参考hystrix简介中dashboard文档

1、使用hystrix-dashboard代码生成对应的war包

1.1 clone代码

git地址:github.com/Netflix-Sku…

1.2 打包

  1. 文档中是使用gradew命令来进行打包,我这边有问题,就直接使用idea的gradle进行打包,如下图所示
  2. 点击build进行编译,然后会在类路径下的build下生成对应的war包

image

2、使用tomcat启动war包

将刚生成的war包放到tomcat的webapps下

3、监听hystrix进程

3.1 打开dashboard的首页

http://localhost:8080/hystrix-dashboard/

image

3.2 监听hystrix进程

  1. 将需要监听的进程放入到stream输入框中(http://host:port/hystrix.stream)
  2. 点击add Stream按钮,点击Monitor Streams
  3. stream可添加多个

image

3.3 查看command当前状态

  1. 第一行表示command的状态,第二行包含线程池的状态,里面包含我们关系的熔断相关的数据
  2. 里面包含成功数、熔断数、bad request数量、超时、拒绝、失败、错误等数量,以及熔断开关状态、99th等,具体可以参照文档进行相关学习
  3. 这些数据都是通过接收被监听hystrix进程计算并发送出来,核心逻辑还是在hystrix-core中,具体详见后面我的关于hystrix源码分析模块
  4. 下图1是监听到的数据,下图二是dashboard的ui展示

image

image