本篇文章为Spring Cloud 各模块演示代码的分支[Hystrix]部分。
先从几个概念开始,了解概念有助于对Hystrix的理解。
熔断、降级、限流的概念
-
雪崩效应
分布式系统中经常会出现某个基础服务不可用造成整个系统不可用的情况, 这种现象被称为服务雪崩效应. 为了应对服务雪崩, 一种常见的做法是手动服务降级.-
定义
雪崩效应:服务提供者 的不可用导致 服务调用者 的不可用,并将不可用 逐渐放大 的过程
下图从上到下看,可以发现随着A不可用,慢慢的B服务还有CD服务都不可用了。 雪崩效应形成的原因
我把服务雪崩的参与者简化为 服务提供者 和 服务调用者, 并将服务雪崩产生的过程分为以下三个阶段来分析形成的原因:
1.服务提供者不可用
2.重试加大流量
3.服务调用者不可用
服务提供者不可用原因
服务雪崩的每个阶段都可能由不同的原因造成, 比如造成 服务不可用的原因有:
硬件故障: 硬件故障可能为硬件损坏造成的服务器主机宕机, 网络硬件故障造成的服务提供者的不可访问.
程序Bug
缓存击穿: 缓存击穿一般发生在缓存应用重启, 所有缓存被清空时,以及短时间内大量缓存失效时. 大量的缓存不命中, 使请求直击后端,造成服务提供者超负荷运行,引起服务不可用.
用户大量请求: 在秒杀和大促开始前,如果准备不充分,用户发起大量请求也会造成服务提供者的不可用.重试加大流量
用户重试:在服务提供者不可用后, 用户由于忍受不了界面上长时间的等待,而不断刷新页面甚至提交表单.
代码逻辑重试:服务调用端的会存在大量服务异常后的重试逻辑.服务调用者不可用
当服务调用者使用 同步调用 时, 会产生大量的等待线程占用系统资源. 一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态, 于是服务雪崩效应产生了.
-
应对策略
熔断:通过 超时机制使得不可用服务的调用快速失败
限流:网关限流、用户交互限流、关闭重试、接口限流。在JAVA中实现接口限流可以用guava的RateLimiter,它实现了令牌桶算法和漏桶算法。
降级:调用服务线程池隔离、依赖服务分类(终止弱依赖服务)
服务自动扩容
以上概念部分摘自 http://kaimingwan.com/post/jia-gou/shi-yong-hystrixwan-cheng-rong-duan-xian-liu-he-jiang-ji
Hystrix 代码示例
- 断路器demo
1. 启动注册中心eureka-a
2.启动服务端spring-cloud-03-hystrix-client
3.启动客户端spring-cloud-03-hystrix-request-a
请求超时触发:http://localhost:6001/hystrix-hello
返回:----------执行降级策略------------
异常捕捉触发: http://localhost:6001/hystrix-handler/** * 配置的断路时间为2秒,但是调用的服务睡眠了3秒。进入降级策略 * @return */ @HystrixCommand(fallbackMethod = "callHelloFailback") public String callHello() { return restTemplate.getForObject("http://client-service/hello", String.class); } public String callHelloFailback(){ System.err.println("----------执行降级策略------------"); return "----------执行降级策略------------"; }
返回:获取异常信息并可以做具体的降级处理
单独API配置:/** * 异常捕获方式的断路器 */ @HystrixCommand(fallbackMethod = "handlerFailback", ignoreExceptions = {BadRequestException.class}) public String handler() { throw new RuntimeException("运行时异常..."); } /** * 异常信息可传递到fallback方法中 */ public String handlerFailback(Throwable e){ System.err.println("异常信息: " + e.getMessage()); return "获取异常信息并可以做具体的降级处理"; }
/** * 对单独API 配置断路由规则,不受配置文件中的配置参数影响 * 如下,配置8秒读取超时,配置文件中的2秒将失效 * 更多commandProperties信息:https://github.com/Netflix/Hystrix/wiki/Configuration */ @HystrixCommand( commandKey = "hiKey", commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", /*KEY*/ value = "8000" /*VALUE*/)}, fallbackMethod = "callHiFailback") public String callhi() { System.err.println("--客户端调用-----"); return restTemplate.getForObject("http://client-service/hi", String.class); } public String callHiFailback(){ System.err.println("----------执行降级策略------------"); return "----------执行降级策略------------"; }
Hystrix DashBoard 服务压力查看器
1.在以上的Demo启动的基础上,启动 spring-cloud-03-hystrix-dashboard
2.访问 http://localhost:5001/hystrix
3.点击进入后可查看所有的请求情况
Hystrix Turbine 集群服务压力查看器
1.在以上的基础上启动 spring-cloud-03-hystrix-request-b
和 集群收集模块turbine spring-cloud-03-hystrix-turbine
这时在dashboard中填入的地址为http://localhost:3000/turbine.stream
点击监控。分别请求 spring-cloud-03-hystrix-request-a
和 spring-cloud-03-hystrix-request-b
的API之后。会发现在监控平台上的Hosts变为了2.两个客户端的请求都能被监控了。
END