9.源码分析---SOFARPC是如何实现故障剔除的? (7)

getInvocationLeastWindowCount方法主要是用来做校验,如果原始的权重为0,或者为-1,那么就返回-1。
因为当前的InvocationStat的权重可能被降权过,所以我们不能按原来的最小窗口调用次数来算,所以这里需要乘以一个比率,然后看是不是小于LEGAL_LEAST_WINDOW_COUNT,返回际权重计算该Invocation的实际最小窗口调用次数。

if判断

我们在分析calculateAverageExceptionRate方法的时候看了,如果总的调用次数为0,那么averageExceptionRate会为-1。代表所有的InvocationStat没有被调用,我们设置忽略。

那么接着往下走,会发现有一个averageExceptionRate是否为0的判断,由于averageExceptionRate =(异常次数/调用次数),所以如果没有异常的时候设置状态为健康。

windowExceptionRateMultipe
windowExceptionRateMultipe这个变量主要是用来看这次被遍历到invocationStat的异常率和平均异常率之比。如果当前的(异常率/平均异常率)>=leastWindowExceptionRateMultiple,默认是6倍,那么就设置当前的invocationStat为异常。

根据MeasureResult进行降权或恢复

调用完ServiceHorizontalMeasureStrategy#measure方法后会返回一个MeasureResult,然会新建一个RegulationRunnable实例,丢到regulationExecutor线程池中执行。

RegulationRunnable是TimeWeindowRegulator的内部类。

RegulationRunnable#run

RegulationRunnable(MeasureResult measureResult) { this.measureResult = measureResult; } public void run() { List<MeasureResultDetail> measureResultDetails = measureResult.getAllMeasureResultDetails(); for (MeasureResultDetail measureResultDetail : measureResultDetails) { try { doRegulate(measureResultDetail); } catch (Exception e) { LOGGER.errorWithApp(measureResult.getMeasureModel().getAppName(), "Error when doRegulate: " + e.getMessage(), e); } } }

RegulationRunnable会在run方法里面遍历所有的measureResult,然后调用doRegulate方法进行降权或恢复的处理

void doRegulate(MeasureResultDetail measureResultDetail) { MeasureState measureState = measureResultDetail.getMeasureState(); InvocationStatDimension statDimension = measureResultDetail.getInvocationStatDimension(); //默认是否进行降级 ,默认为否 ServiceHorizontalRegulationStrategy boolean isDegradeEffective = regulationStrategy.isDegradeEffective(measureResultDetail); if (isDegradeEffective) { measureResultDetail.setLogOnly(false); if (measureState.equals(MeasureState.ABNORMAL)) { //这里是为了以防对太多节点做了降权,所以默认限制只能最多给两个节点降权 boolean isReachMaxDegradeIpCount = regulationStrategy.isReachMaxDegradeIpCount(measureResultDetail); if (!isReachMaxDegradeIpCount) { //降权 WeightDegradeStrategy degradeStrategy.degrade(measureResultDetail); } else { String appName = measureResult.getMeasureModel().getAppName(); if (LOGGER.isInfoEnabled(appName)) { LOGGER.infoWithApp(appName, LogCodes.getLog(LogCodes.INFO_REGULATION_ABNORMAL_NOT_DEGRADE, "Reach degrade number limit.", statDimension.getService(), statDimension.getIp(), statDimension.getAppName())); } } } else if (measureState.equals(MeasureState.HEALTH)) { boolean isExistDegradeList = regulationStrategy.isExistInTheDegradeList(measureResultDetail); if (isExistDegradeList) { //恢复 recoverStrategy.recover(measureResultDetail); regulationStrategy.removeFromDegradeList(measureResultDetail); } //没有被降级过,因此不需要被恢复。 } } else { measureResultDetail.setLogOnly(true); if (measureState.equals(MeasureState.ABNORMAL)) { //这个时候调用degrade,主要是打印日志用的 degradeStrategy.degrade(measureResultDetail); String appName = measureResult.getMeasureModel().getAppName(); if (LOGGER.isInfoEnabled(appName)) { LOGGER.infoWithApp(appName, LogCodes.getLog(LogCodes.INFO_REGULATION_ABNORMAL_NOT_DEGRADE, "Degrade switch is off", statDimension.getService(), statDimension.getIp(), statDimension.getAppName())); } } } } }

我们分两种情况进行分析。

如果该节点是异常节点
首先会调用ServiceHorizontalRegulationStrategy#isReachMaxDegradeIpCount方法。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppwdd.html