简述
由于服务调用的复杂性,可能因为某个节点服务不可用导致任务积压,最终导致系统瘫痪,所以我们需要断路器等服务保护机制。
断路器原理
(图片来自于官方wiki)
https://github.com/Netflix/Hystrix/blob/2.0.x/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCircuitBreaker.java
allowrequest:判断请求是否被允许
@Override
public boolean allowRequest() {
if (properties.circuitBreakerForceOpen().get()) {
//强制开启 拒绝请求
return false;
}
if (properties.circuitBreakerForceClosed().get()) {
//强制关闭 执行isopen逻辑
isOpen();
return true;
}
return !isOpen() || allowSingleTest();
}
//休眠时间的判断和设置
public boolean allowSingleTest() {
long timeCircuitOpenedOrWasLastTested = circuitOpenedOrLastTestedTime.get();
if (circuitOpen.get() && System.currentTimeMillis() > timeCircuitOpenedOrWasLastTested + properties.circuitBreakerSleepWindowInMilliseconds().get()) {
if (circuitOpenedOrLastTestedTime.compareAndSet(timeCircuitOpenedOrWasLastTested, System.currentTimeMillis())) {
return true;
}
}
return false;
}
isopen():判断熔断器是否打开
@Override
public boolean isOpen() {
if (circuitOpen.get()) {
//如果已经打开我们就直接返回true了
return true;
}
//获取当前key的运行状态
HealthCounts health = metrics.getHealthCounts();
//QPS 检查我们是否超过了statisticsWindowVolumeThreshold
if (health.getTotalRequests() < properties.circuitBreakerRequestVolumeThreshold().get()) {
//没有超过就不开启熔断器了
return false;
}
//错误率在合理范围内就不开启
if (health.getErrorPercentage() < properties.circuitBreakerErrorThresholdPercentage().get()) {
return false;
} else {
// 错误率太高 开启熔断器
if (circuitOpen.compareAndSet(false, true)) {
// 设置开启时间
circuitOpenedOrLastTestedTime.set(System.currentTimeMillis());
return true;
} else {
// 被其他线程改过了 且值肯定为true
return true;
}
}
}
}
markSuccess:如果命令调用成功了,将打开的断路器关闭,重置运行指标
public void markSuccess() {
if (circuitOpen.get()) {
if (circuitOpen.compareAndSet(true, false)) {
metrics.resetStream();
}
}
}
进程隔离
- 为每一个依赖服务创建一个线程池,使得就算某个依赖出现问题也不会影响其他依赖的调用
- 某个线程池的指标完全能反应某个服务的指标,因为这个线程池全是这个服务
- 并发
服务降级
通过指定fallbackMethod 返回给调用者错误信息来实现降级处理响应,特别是对于一些批处理和离线计算命令
请求缓存
通过注解CacheResult,CacheRemove来实现缓存读写,注解CacheKey来设置key值
请求合并
通过HystrixCollpser来实现请求合并,以达到减少线程和通信消耗.
实现原理:在执行command之前,在一定时间窗内,针对同一个依赖的请求,把请求数据合并(服务提供方也需要有处理合并后数据的服务)
断路器监控
在断路器的实现中,有一个很重要的东西是度量指标,这些指标都是运行过程中产生的重要信息。这些信息除了在断路器实现中使用以外,还有一个重要用途就是:hystrix仪表盘。如果要实现集群的监控还需要集成Turbine.
单点监控
图片来源https://github.com/Netflix/Hystrix/wiki/Dashboard
实心圆:有两种含义。1.健康度 绿-》黄 -》橙 -》红 2.流量越大实心圆越大
曲线:两分钟内流量的变化
其他指标
集群监控
https://github.com/Netflix/turbine/wiki