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

getInvocationStatSnapshots

public static List<InvocationStat> getInvocationStatSnapshots(List<InvocationStat> stats) { List<InvocationStat> snapshots = new ArrayList<InvocationStat>(stats.size()); for (InvocationStat stat : stats) { //赋值一个InvocationStat出来 InvocationStat snapshot = stat.snapshot(); //如果被调用的次数小于0 if (snapshot.getInvokeCount() <= 0) { if (stat.getUselessCycle().incrementAndGet() > 6) { // 6 个时间窗口无调用,删除统计 InvocationStatFactory.removeInvocationStat(stat); InvocationStatDimension dimension = stat.getDimension(); String appName = dimension.getAppName(); if (LOGGER.isDebugEnabled(appName)) { LOGGER.debugWithApp(appName, "Remove invocation stat : {}, {} because of useless cycle > 6", dimension.getDimensionKey(), dimension.getProviderInfo()); } } } else { //如果被调用了,那么就从新计数 stat.getUselessCycle().set(0); snapshots.add(snapshot); } } return snapshots; } //ServiceExceptionInvocationStat#snapshot public InvocationStat snapshot() { ServiceExceptionInvocationStat invocationStat = new ServiceExceptionInvocationStat(dimension); invocationStat.setInvokeCount(getInvokeCount()); invocationStat.setExceptionCount(getExceptionCount()); return invocationStat; }

首先 这个方法里面首先是遍历所有的InvocationStat,然后调用snapshot创建一个新的InvocationStat实例。

其次 校验新的InvocationStat实例调用次数是不是小于等于0,如果是,说明没有在时间窗口内没有被调用过一次,那么就再看是不是在6 个时间窗口无调用,如果是,那么就删除统计数据

然后返回新的InvocationStat集合

calculateAverageExceptionRate

private double calculateAverageExceptionRate(List<InvocationStat> invocationStats, long leastWindowCount) { long sumException = 0; long sumCall = 0; for (InvocationStat invocationStat : invocationStats) { long invocationLeastWindowCount = getInvocationLeastWindowCount(invocationStat, ProviderInfoWeightManager.getWeight(invocationStat.getDimension().getProviderInfo()), leastWindowCount); //统计所有的invocationStat被调用的次数,和异常次数 if (invocationLeastWindowCount != -1 && invocationStat.getInvokeCount() >= invocationLeastWindowCount) { sumException += invocationStat.getExceptionCount(); sumCall += invocationStat.getInvokeCount(); } } if (sumCall == 0) { return -1; } //计算异常比率 return CalculateUtils.divide(sumException, sumCall); } private long getInvocationLeastWindowCount(InvocationStat invocationStat, Integer weight, long leastWindowCount) { //目标地址原始权重 InvocationStatDimension statDimension = invocationStat.getDimension(); Integer originWeight = statDimension.getOriginWeight(); if (originWeight == 0) { LOGGER.errorWithApp(statDimension.getAppName(), "originWeight is 0,but is invoked. service[" + statDimension.getService() + "];ip[" + statDimension.getIp() + "]."); return -1; } else if (weight == null) { //如果地址还未被调控过或者已经恢复。 return leastWindowCount; } else if (weight == -1) { //如果地址被剔除 return -1; } //这里主要是根据Invocation的实际权重计算该Invocation的实际最小窗口调用次数 double rate = CalculateUtils.divide(weight, originWeight); long invocationLeastWindowCount = CalculateUtils.multiply(leastWindowCount, rate); return invocationLeastWindowCount < LEGAL_LEAST_WINDOW_COUNT ? LEGAL_LEAST_WINDOW_COUNT : invocationLeastWindowCount; }

这个方法总的来说就是遍历所有的InvocationStat,然后求和说有的调用次数和异常次数,然后用(异常次数/调用次数)计算平均异常比率。

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

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