对HystrixCircuitBreaker源码的解析
public interface HystrixCircuitBreaker {
public boolean allowRequest();
public boolean isOpen();
void markSuccess();
}
allowRequest:代表是否允许请求
isOpen:代表是否打开
markSuccess:关闭断路器
HystrixCircuitBreakerImpl实现了HystrixCircuitBreaker
public void markSuccess() {
if (circuitOpen.get()) {
//设置关闭
if (circuitOpen.compareAndSet(true,false)) {
metrics.resetStream();
}
}
}
下面说说open方法
public boolean isOpen() {
if (circuitOpen.get()) {
return true;
}
HealthCounts health =metrics.getHealthCounts();
//是否达到阈值,默认20
if (health.getTotalRequests()< properties.circuitBreakerRequestVolumeThreshold().get()) {
return false;
}
//是否达到错误阈值
if (health.getErrorPercentage()
return false;
}else {//打开开关
if (circuitOpen.compareAndSet(false,true)) {//记录当前时间
circuitOpenedOrLastTestedTime.set(System.currentTimeMillis());
return true;
}else {
return true;
}
}
}
public boolean allowRequest() {
//强制打开开关
if (properties.circuitBreakerForceOpen().get()) {
return false;
}//强制关闭
if (properties.circuitBreakerForceClosed().get()) {
isOpen();
return true;
}
return !isOpen() || allowSingleTest();
}
1、如果开关已开,不允许访问,降级执行
2、还有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;
}