在上篇文章中提到,onError()或onSuccess()时都会去计算错误率等指标,具体是由CircuitBreakerMetrics实现
一:CircuitBreaker.Metrics 指标度量接口
该接口定义了一系列获取度量指标的方法,其中包括如下:
//度量指标接口,用于观察熔断器的各项指标
interface Metrics {
// 返回失败率百分比,如果调用数小于MINIMUM_NUMBER_OF_CALLS,返回-1
float getFailureRate();
//返回慢调用率百分比,如果调用数小于MINIMUM_NUMBER_OF_CALLS,返回-1
float getSlowCallRate();
//慢调用请求总数
int getNumberOfSlowCalls();
//慢调用成功总数
int getNumberOfSlowSuccessfulCalls();
//慢调用失败总数
int getNumberOfSlowFailedCalls();
//环形缓冲区的最大调用数
int getNumberOfBufferedCalls();
// 失败调用总数
int getNumberOfFailedCalls();
// 在打开状态下,返回当前不被允许请求调用的数量,在关闭和半开状态下,总返回0
long getNumberOfNotPermittedCalls();
//成功调用总数
int getNumberOfSuccessfulCalls();
}
二:CircuitBreakerMetrics类
是CircuitBreaker.Metrics接口的实现类,具体内容就是实现了CircuitBreaker.Metrics 定义的方法
//慢调用率
private float getSlowCallRate(Snapshot snapshot) {
int bufferedCalls = snapshot.getTotalNumberOfCalls();
if (bufferedCalls == 0 || bufferedCalls < minimumNumberOfCalls) {
return -1.0f;
}
return snapshot.getSlowCallRate();
}
//失败率
private float getFailureRate(Snapshot snapshot) {
//总共调用的次数
int bufferedCalls = snapshot.getTotalNumberOfCalls();
if (bufferedCalls == 0 || bufferedCalls < minimumNumberOfCalls) {
//ringBitSet中个数没有达到ringBufferSize大小,返回-1.0f,不计算失败率
return -1.0f;
}
//返回失败率:totalNumberOfFailedCalls * 100.0f / totalNumberOfCalls
return snapshot.getFailureRate();
}
onError()和onSuccess()方法是由上篇文章提到的状态机CircuitBreakerStateMachine的状态类中的onError()和onSuccess()方法调用的,检查是否达到了错误率阈值checkIfThresholdsExceeded() 进而调用状态机的状态转换方法 stateTransition()
/**
* Records a successful call and checks if the thresholds are exceeded.
* 成功调用时检查是否是慢调用,如果是慢调用,先发布慢调用事件,再统计慢调用率
* @return the result of the check
*/
public Result onSuccess(long duration, TimeUnit durationUnit) {
Snapshot snapshot;
if (durationUnit.toNanos(duration) > slowCallDurationThresholdInNanos) {
snapshot = metrics.record(duration, durationUnit, Outcome.SLOW_SUCCESS);
} else {
snapshot = metrics.record(duration, durationUnit, Outcome.SUCCESS);
}
return checkIfThresholdsExceeded(snapshot);
}
/**
* 失败时就会调用此方法,发布慢/错误事件,并检查是否达到阈值
* 1.先记录请求,即总请求次数,错误请求次数等+1
* 2. 计算失败率/慢调用率,是否达到阈值
*/
public Result onError(long duration, TimeUnit durationUnit) {
Snapshot snapshot;
if (durationUnit.toNanos(duration) > slowCallDurationThresholdInNanos) {
//慢调用,调用Core.Metrics 记录请求数
snapshot = metrics.record(duration, durationUnit, Outcome.SLOW_ERROR);
} else {
//错误调用,调用Core.Metrics 记录请求数
snapshot = metrics.record(duration, durationUnit, Outcome.ERROR);
}
return checkIfThresholdsExceeded(snapshot);
}
// 检查错误率/慢调用率是否达到阈值
private Result checkIfThresholdsExceeded(Snapshot snapshot) {
//获取失败率
float failureRateInPercentage = getFailureRate(snapshot);
if (failureRateInPercentage == -1) {
//小于缓冲大小,还未达到检查阈值
return Result.BELOW_MINIMUM_CALLS_THRESHOLD;
}
if (failureRateInPercentage >= failureRateThreshold) {
//超过阈值
return Result.ABOVE_THRESHOLDS;
}
//慢调用率
float slowCallsInPercentage = getSlowCallRate(snapshot);
if (slowCallsInPercentage >= slowCallRateThreshold) {
return Result.ABOVE_THRESHOLDS;
}
return Result.BELOW_THRESHOLDS;
}
还定义了检查是否达到阈值的枚举值:
enum Result {
BELOW_THRESHOLDS,
ABOVE_THRESHOLDS,
BELOW_MINIMUM_CALLS_THRESHOLD
}
总结
CircuitBreakerMetrics主要用来计算度量的各种指标