Spring Cloud 教程第九章 Ribbon 整合断路器 Hystrix

JAVA herman 132浏览 0评论

上一章我们讲了 Feign 开启断路器 Hystrix 的功能。由于 Feign 本身已经整合了 Ribbon 和 Hystrix 的部分功能,所以用起来比较简单。但是 Ribbon 中怎么使用 Hystrix 呢?本文将通过一个小 demo,教大家如何在使用 Ribbon 中加入 Hystrix 的功能。

Hystrix 提供了一个基于命令模式 HystrixCommand 来包装依赖调用逻辑,其每个命令在单独线程中或信号授权下执行。(Command 是在 Receiver 和 Invoker 之间添加的中间层,Command 实现了对 Receiver 的封装)。Hystrix 支持两种隔离策略:线程池隔离和信号量隔离(都是限制对共享资源的并发访问量)。

  • ThreadPool:根据配置把不同命令分配到不同的线程池中,这是比较常用的隔离策略,其优点是隔离性好,并且可以配置断路某个依赖被设置断路之后,系统不会再尝试新起线程运行它,而是直接提示失败,或返回 fallback 值它的缺点是新起线程执行命令,在执行时必然涉及上下文的切换,这会造成一定的性能消耗但是 Netflix 做过实验,这种消耗对比其带来的价值是完全可以接受的,具体的数据参见 Hystrix-Wiki
  • Semaphores:顾名思义就是使用一个信号量来做隔离,开发者可以限制系统对某一个依赖的最高并发数,这个基本上就是一个限流的策略。每次调用依赖时都会检查一下是否到达信号量的限制值,如达到,则拒绝该策略的优点是不新起线程执行命令,减少上下文切换,缺点是无法配置断路,每次都一定会去尝试获取信号量。

为了简单,我们直接对之前的案例中的 xttblog-cloud-ribbon 项目进行一下整改。当然为了不污染之前的项目案例,我们还是新建一个工程:xttblog-ribbon-hystrix。pom.xml 的配置是一样的,我就略过了。application.yml 中,只改了一下端口和服务名称:

server:
  port: 7081

eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/

spring:
  application:
    name: xttblog-ribbon-hystrix

Springboot 入口类中,需要配置 @EnableCircuitBreaker 注解:

@SpringBootApplication
@EnableDiscoveryClient
//开启断路器功能
@EnableCircuitBreaker
public class RibbonHystrixApplication {

    //开启软均衡负载
    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(RibbonHystrixApplication.class, args);
    }
}

RibbonController 和 CalService 保持不变,CalServiceImpl 的改动如下:

@Service
public class CalServiceImpl implements CalService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Override
    //指定断路后的回调方法(回调方法必须与原方法参数类型相同、返回值类型相同、方法名可以不同)
    @HystrixCommand(fallbackMethod="hystrixFallback")
    public Integer add(Integer a, Integer b) {
        String reqURL = "http://com.xttblog-cloud-producer/cal/add?a=" + a + "&b=" + b;
        test();
        return restTemplate.getForEntity(reqURL, Integer.class).getBody();
    }

    public Integer hystrixFallback(Integer a, Integer b){
        System.out.println("服务熔断了。。。。");
        return -1024;
    }

    private void test(){
        ServiceInstance serviceInstance = loadBalancerClient.choose("com.xttblog-cloud-producer");
        System.out.println("Host:" + serviceInstance.getHost()
                + ",ServiceId:" + serviceInstance.getServiceId()
                + ",Port:" + serviceInstance.getPort());
    }
}

使用 @HystrixCommand(fallbackMethod="hystrixFallback") 指定断路后,要执行的方法即可。

做完以上的代码编写,我们就可以依次启动 xttblog-eureka-server、xttblog-cloud-producer、xttblog-ribbon-hystrix 三个项目。然后在浏览器里输入 http://localhost:7081/test?a=1&b=10 进行访问,没有问题后,我们关闭掉 xttblog-cloud-producer 服务,再次刷新浏览器,返回结果中若有“-1024”,则说明成功的进行了熔断。

Hystrix 的配置参数

Hystrix 的大部分配置都是 hystrix.command.[HystrixCommandKey] 开头

其中 [HystrixCommandKey] 是可变的,默认是 default,即:hystrix.command.default(对于 Zuul 而言,CommandKey 就是 service id)

它常见的有以下几个配置

  • hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
    用来设置 thread 和 semaphore 两种隔离策略的超时时间,默认值是1000
    建议设置这个参数,在 Hystrix-1.4.0 之前,semaphore-isolated 隔离策略是不能超时的,1.4.0 开始 semaphore-isolated 也支持超时时间了

  • hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests
    此值并非 TPS、QPS、RPS 等都是相对值,它指的是 1 秒时间窗口内的事务 / 查询 / 请求,它是一个绝对值,无时间窗口
    相当于亚毫秒级的,指任意时间点允许的并发数,当请求达到或超过该设置值后,其其余就会被拒绝,默认值是100

  • hystrix.command.default.execution.timeout.enabled
    是否开启超时,默认为true

  • hystrix.command.default.execution.isolation.thread.interruptOnTimeout
    发生超时是是否中断线程,默认是true

  • hystrix.command.default.execution.isolation.thread.interruptOnCancel
    取消时是否中断线程,默认是false

  • hystrix.command.default.circuitBreaker.requestVolumeThreshold
    当在配置时间窗口内达到此数量的失败后,进行短路,默认20个

  • hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds
    短路多久以后开始尝试是否恢复,默认5s

  • hystrix.command.default.circuitBreaker.errorThresholdPercentage
    出错百分比阈值,当达到此阈值后,开始短路,默认50%

  • hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests
    调用线程允许请求 HystrixCommand.GetFallback() 的最大数量,默认10,超出时将会有异常抛出
    注意:该项配置对于 thread 隔离模式也起作用

以上就是列举的一些常见配置,更多内容可参考:https://github.com/Netflix/Hystrix/wiki/Configuration

本文源码已共享至:https://github.com/xmt1139057136/xttblog-cloud

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847,QQ3群:187424846。QQ群进群密码:xttblog,想加微信群的朋友,可以微信搜索:xmtxtt,备注:“xttblog”,添加助理微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » Spring Cloud 教程第九章 Ribbon 整合断路器 Hystrix