Hystrix简介
- Hystrix的设计目标
- 对来自依赖的延迟和故障进行防护和控制——这些依赖通常都是通过网络访问的
- 阻止故障的连锁反应
- 快速失败并迅速恢复
- 回退并优雅降级
- 提供近实时的监控与告警
- Hystrix遵循的设计原则
- 防止任何单独的依赖耗尽资源(线程)
- 过载立即切断并快速失败,防止排队
- 尽可能提供回退以保护用户免受故障
- 使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一个依赖的影响
- 通过近实时的指标,监控和告警,确保故障被及时发现
- 通过动态修改配置属性,确保故障及时恢复
- 防止整个依赖客户端执行失败,而不仅仅是网络通信
- Hystrix如何实现这些设计目标
- 使用命令模式将所有对外部服务(或依赖关系)的调用包装在HystrixCommand或HystrixObservableCommand对象中,并将该对象放在单独的线程中执行
- 每个依赖都维护着一个线程池(或信号量),线程池被耗尽则拒绝请求(而不是让请求排队)
- 记录请求成功,失败,超时和线程拒绝
- 服务错误百分比超过了阈值,熔断器开关自动打开,一段时间内停止对该服务的所有请求
- 请求失败,被拒绝,超时或熔断时执行降级逻辑
- 近实时地监控指标和配置的修改
- 通过上述的描述,大致能知道Hystrix是干什么的,能起到什么作用。
- 对于Hystrix不了解的同学可以看这篇文章:Hystrix原理与实战
示例演示
- 启动
soul-admin和soul-bootstrap
需要注意的是soul-bootstrap网关的 pom.xml 文件中添加 hystrix的支持。<!-- soul hystrix plugin start--> <dependency> <groupId>org.dromara</groupId> <artifactId>soul-spring-boot-starter-plugin-hystrix</artifactId> <version>${last.version}</version> </dependency> <!-- soul hystrix plugin end--> - 在
soul-admin–> 插件管理 –> hystrix,设置为开启。并且在hystrix插件处设置选择其和规则

- 跳闸最小请求数量 :最小的请求量,至少要达到这个量才会触发熔断
- 错误百分比阀值 : 这段时间内,发生异常的百分比。
- 跳闸休眠时间(ms) :熔断以后恢复的时间。
- 分组Key: 一般设置为:contextPath,默认为divide的selector名。
- 命令Key: 一般设置为具体的 路径接口,默认为divide的规则名。
- 失败降级URL:失败后调用的的url
- 注:为了演示效果,把并发量和容错阈值都设置的比较小
- 为了演示高并发,使用Superbenchmarker如下命令:
sb -c 10 -N 10 -u http://localhost:9195/http/order/findById?id=2 - 然后看控制台的log,发现Hystrix起作用了
2021-02-01 22:56:24.569 INFO 14096 --- [work-threads-42] o.d.soul.plugin.base.AbstractSoulPlugin : hystrix selector success match , selector name :testH 2021-02-01 22:56:24.569 INFO 14096 --- [work-threads-43] o.d.soul.plugin.base.AbstractSoulPlugin : hystrix selector success match , selector name :testH 2021-02-01 22:56:24.569 ERROR 14096 --- [work-threads-41] o.d.soul.plugin.hystrix.HystrixPlugin : hystrix execute have circuitBreaker is Open! groupKey:/http,commandKey:/order/findById 2021-02-01 22:56:24.569 INFO 14096 --- [work-threads-42] o.d.soul.plugin.base.AbstractSoulPlugin : hystrix rule success match , rule name :1 2021-02-01 22:56:24.569 INFO 14096 --- [work-threads-43] o.d.soul.plugin.base.AbstractSoulPlugin : hystrix rule success match , rule name :1 2021-02-01 22:56:24.569 ERROR 14096 --- [work-threads-42] o.d.soul.plugin.hystrix.HystrixPlugin : hystrix execute have circuitBreaker is Open! groupKey:/http,commandKey:/order/findById 2021-02-01 22:56:24.569 ERROR 14096 --- [work-threads-43] o.d.soul.plugin.hystrix.HystrixPlugin : hystrix execute have circuitBreaker is Open! groupKey:/http,commandKey:/order/findById
代码跟踪
通过上面的log或者根据项目的结构,我们可以定位到soul-plugin-hystrix的HystrixPlugin这个类,看一下它的doExecute方法
protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
assert soulContext != null;
// 从当前web请求匹配上的规则取出熔断配置
final HystrixHandle hystrixHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), HystrixHandle.class);
if (StringUtils.isBlank(hystrixHandle.getGroupKey())) {
hystrixHandle.setGroupKey(Objects.requireNonNull(soulContext).getModule());
}
if (StringUtils.isBlank(hystrixHandle.getCommandKey())) {
hystrixHandle.setCommandKey(Objects.requireNonNull(soulContext).getMethod());
}
Command command = fetchCommand(hystrixHandle, exchange, chain);
return Mono.create(s -> {
Subscription sub = command.fetchObservable().subscribe(s::success,
s::error, s::success);
s.onCancel(sub::unsubscribe);
// 断路器 判断是否熔断
if (command.isCircuitBreakerOpen()) {
log.error("hystrix execute have circuitBreaker is Open! groupKey:{},commandKey:{}", hystrixHandle.getGroupKey(), hystrixHandle.getCommandKey());
}
}).doOnError(throwable -> {
log.error("hystrix execute exception:", throwable);
exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.ERROR.getName());
chain.execute(exchange);
}).then();
}
- 上面这个方法通过execute()方法,以同步堵塞方式执行run(),只支持接收一个值对象。hystrix会从线程池中取一个线程来执行run(),并等待返回值。
public Observable<Void> fetchObservable() { return RxReactiveStreams.toObservable(this.execute()); }
848

被折叠的 条评论
为什么被折叠?



