use of com.alipay.sofa.rpc.client.aft.InvocationStat in project sofa-rpc by sofastack.
the class FaultToleranceSubscriber method onEvent.
@Override
public void onEvent(Event originEvent) {
Class eventClass = originEvent.getClass();
if (eventClass == ClientSyncReceiveEvent.class) {
if (!FaultToleranceConfigManager.isEnable()) {
return;
}
// 同步结果
ClientSyncReceiveEvent event = (ClientSyncReceiveEvent) originEvent;
ConsumerConfig consumerConfig = event.getConsumerConfig();
ProviderInfo providerInfo = event.getProviderInfo();
InvocationStat result = InvocationStatFactory.getInvocationStat(consumerConfig, providerInfo);
if (result != null) {
result.invoke();
Throwable t = event.getThrowable();
if (t != null) {
result.catchException(t);
}
}
} else if (eventClass == ClientAsyncReceiveEvent.class) {
if (!FaultToleranceConfigManager.isEnable()) {
return;
}
// 异步结果
ClientAsyncReceiveEvent event = (ClientAsyncReceiveEvent) originEvent;
ConsumerConfig consumerConfig = event.getConsumerConfig();
ProviderInfo providerInfo = event.getProviderInfo();
InvocationStat result = InvocationStatFactory.getInvocationStat(consumerConfig, providerInfo);
if (result != null) {
result.invoke();
Throwable t = event.getThrowable();
if (t != null) {
result.catchException(t);
}
}
} else if (eventClass == ProviderInfoRemoveEvent.class) {
ProviderInfoRemoveEvent event = (ProviderInfoRemoveEvent) originEvent;
ConsumerConfig consumerConfig = event.getConsumerConfig();
ProviderGroup providerGroup = event.getProviderGroup();
if (!ProviderHelper.isEmpty(providerGroup)) {
for (ProviderInfo providerInfo : providerGroup.getProviderInfos()) {
InvocationStatFactory.removeInvocationStat(consumerConfig, providerInfo);
}
}
} else if (eventClass == ProviderInfoUpdateEvent.class) {
ProviderInfoUpdateEvent event = (ProviderInfoUpdateEvent) originEvent;
ConsumerConfig consumerConfig = event.getConsumerConfig();
List<ProviderInfo> add = new ArrayList<ProviderInfo>();
List<ProviderInfo> remove = new ArrayList<ProviderInfo>();
ProviderHelper.compareGroup(event.getOldProviderGroup(), event.getNewProviderGroup(), add, remove);
for (ProviderInfo providerInfo : remove) {
InvocationStatFactory.removeInvocationStat(consumerConfig, providerInfo);
}
} else if (eventClass == ProviderInfoUpdateAllEvent.class) {
ProviderInfoUpdateAllEvent event = (ProviderInfoUpdateAllEvent) originEvent;
ConsumerConfig consumerConfig = event.getConsumerConfig();
List<ProviderInfo> add = new ArrayList<ProviderInfo>();
List<ProviderInfo> remove = new ArrayList<ProviderInfo>();
ProviderHelper.compareGroups(event.getOldProviderGroups(), event.getNewProviderGroups(), add, remove);
for (ProviderInfo providerInfo : remove) {
InvocationStatFactory.removeInvocationStat(consumerConfig, providerInfo);
}
}
}
use of com.alipay.sofa.rpc.client.aft.InvocationStat in project sofa-rpc by sofastack.
the class ServiceHorizontalMeasureStrategy method measure.
@Override
public MeasureResult measure(MeasureModel measureModel) {
MeasureResult measureResult = new MeasureResult();
measureResult.setMeasureModel(measureModel);
String appName = measureModel.getAppName();
List<InvocationStat> stats = measureModel.getInvocationStats();
if (!CommonUtils.isNotEmpty(stats)) {
return measureResult;
}
// 如果有被新剔除的InvocationStat,则不会存在于该次获取结果中。
List<InvocationStat> invocationStats = getInvocationStatSnapshots(stats);
long timeWindow = FaultToleranceConfigManager.getTimeWindow(appName);
/* leastWindowCount在同一次度量中保持不变*/
long leastWindowCount = FaultToleranceConfigManager.getLeastWindowCount(appName);
leastWindowCount = leastWindowCount < LEGAL_LEAST_WINDOW_COUNT ? LEGAL_LEAST_WINDOW_COUNT : leastWindowCount;
/* 计算平均异常率和度量单个ip的时候都需要使用到appWeight*/
double averageExceptionRate = calculateAverageExceptionRate(invocationStats, leastWindowCount);
double leastWindowExceptionRateMultiple = FaultToleranceConfigManager.getLeastWindowExceptionRateMultiple(appName);
for (InvocationStat invocationStat : invocationStats) {
MeasureResultDetail measureResultDetail = null;
InvocationStatDimension statDimension = invocationStat.getDimension();
long windowCount = invocationStat.getInvokeCount();
long invocationLeastWindowCount = getInvocationLeastWindowCount(invocationStat, ProviderInfoWeightManager.getWeight(statDimension.getProviderInfo()), leastWindowCount);
if (averageExceptionRate == -1) {
measureResultDetail = new MeasureResultDetail(statDimension, MeasureState.IGNORE);
} else {
if (invocationLeastWindowCount != -1 && windowCount >= invocationLeastWindowCount) {
double windowExceptionRate = invocationStat.getExceptionRate();
if (averageExceptionRate == 0) {
measureResultDetail = new MeasureResultDetail(statDimension, MeasureState.HEALTH);
} else {
double windowExceptionRateMultiple = CalculateUtils.divide(windowExceptionRate, averageExceptionRate);
measureResultDetail = windowExceptionRateMultiple >= leastWindowExceptionRateMultiple ? new MeasureResultDetail(statDimension, MeasureState.ABNORMAL) : new MeasureResultDetail(statDimension, MeasureState.HEALTH);
}
measureResultDetail.setAbnormalRate(windowExceptionRate);
measureResultDetail.setAverageAbnormalRate(averageExceptionRate);
measureResultDetail.setLeastAbnormalRateMultiple(leastWindowExceptionRateMultiple);
} else {
measureResultDetail = new MeasureResultDetail(statDimension, MeasureState.IGNORE);
}
}
measureResultDetail.setWindowCount(windowCount);
measureResultDetail.setTimeWindow(timeWindow);
measureResultDetail.setLeastWindowCount(invocationLeastWindowCount);
measureResult.addMeasureDetail(measureResultDetail);
}
logMeasureResult(measureResult, timeWindow, leastWindowCount, averageExceptionRate, leastWindowExceptionRateMultiple);
InvocationStatFactory.updateInvocationStats(invocationStats);
return measureResult;
}
use of com.alipay.sofa.rpc.client.aft.InvocationStat in project sofa-rpc by sofastack.
the class ServiceHorizontalMeasureStrategy method calculateAverageExceptionRate.
/**
* 计算平均异常率,如果调用次数小于leastWindowCount则不参与计算。 如果所有调用次数均为0则返回-1
*
* @param invocationStats List<InvocationStat>
* @param leastWindowCount leastWindowCount
* @return The average exception rate of all invocation statics
*/
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);
if (invocationLeastWindowCount != -1 && invocationStat.getInvokeCount() >= invocationLeastWindowCount) {
sumException += invocationStat.getExceptionCount();
sumCall += invocationStat.getInvokeCount();
}
}
if (sumCall == 0) {
return -1;
}
return CalculateUtils.divide(sumException, sumCall);
}
use of com.alipay.sofa.rpc.client.aft.InvocationStat in project sofa-rpc by sofastack.
the class ServiceHorizontalMeasureStrategy method getInvocationStatSnapshots.
/**
* 对批量Invocation对应的InvocationStat进行一个快照
*
* @param stats Dimensions of invocation statistics
* @return List<InvocationStat>
*/
public static List<InvocationStat> getInvocationStatSnapshots(List<InvocationStat> stats) {
List<InvocationStat> snapshots = new ArrayList<InvocationStat>(stats.size());
for (InvocationStat stat : stats) {
InvocationStat snapshot = stat.snapshot();
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;
}
use of com.alipay.sofa.rpc.client.aft.InvocationStat in project sofa-rpc by sofastack.
the class ServiceHorizontalMeasureStrategy method logMeasureResult.
/**
* Print the measurement result details for each time window.
* @param measureResult
* @param timeWindow
* @param leastWindowCount
* @param averageExceptionRate
* @param leastWindowExceptionRateMultiple
*/
private void logMeasureResult(MeasureResult measureResult, long timeWindow, long leastWindowCount, double averageExceptionRate, double leastWindowExceptionRateMultiple) {
if (measureResult == null) {
return;
}
MeasureModel measureModel = measureResult.getMeasureModel();
String appName = measureModel.getAppName();
if (!LOGGER.isDebugEnabled(appName)) {
return;
}
String service = measureModel.getService();
List<InvocationStat> stats = measureModel.getInvocationStats();
List<MeasureResultDetail> details = measureResult.getAllMeasureResultDetails();
StringBuilder info = new StringBuilder();
info.append("measure info: service[" + service + "];stats{");
for (InvocationStat stat : stats) {
info.append(stat.getDimension().getIp());
info.append(",");
}
if (stats.size() > 0) {
info.deleteCharAt(info.length() - 1);
}
info.append("};details{");
info.append("timeWindow[" + timeWindow + "];leastWindowCount[" + leastWindowCount + "];averageExceptionRate[" + averageExceptionRate + "];leastWindowExceptionRateMultiple[" + leastWindowExceptionRateMultiple + "];");
info.append("detail[");
for (MeasureResultDetail detail : details) {
String ip = detail.getInvocationStatDimension().getIp();
double abnormalRate = detail.getAbnormalRate();
long invocationLeastWindowCount = detail.getLeastWindowCount();
String measureState = detail.getMeasureState().name();
info.append("(ip:" + ip + ",abnormalRate:" + abnormalRate + ",invocationLeastWindowCount:" + invocationLeastWindowCount + ",measureState:" + measureState + ")");
}
info.append("]");
LOGGER.debugWithApp(appName, info.toString());
}
Aggregations