Search in sources :

Example 1 with InvocationStat

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);
        }
    }
}
Also used : InvocationStat(com.alipay.sofa.rpc.client.aft.InvocationStat) ArrayList(java.util.ArrayList) ProviderInfo(com.alipay.sofa.rpc.client.ProviderInfo) ConsumerConfig(com.alipay.sofa.rpc.config.ConsumerConfig) ProviderGroup(com.alipay.sofa.rpc.client.ProviderGroup) List(java.util.List) ArrayList(java.util.ArrayList)

Example 2 with InvocationStat

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;
}
Also used : MeasureResult(com.alipay.sofa.rpc.client.aft.MeasureResult) InvocationStat(com.alipay.sofa.rpc.client.aft.InvocationStat) InvocationStatDimension(com.alipay.sofa.rpc.client.aft.InvocationStatDimension) MeasureResultDetail(com.alipay.sofa.rpc.client.aft.MeasureResultDetail)

Example 3 with InvocationStat

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);
}
Also used : InvocationStat(com.alipay.sofa.rpc.client.aft.InvocationStat)

Example 4 with InvocationStat

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;
}
Also used : InvocationStat(com.alipay.sofa.rpc.client.aft.InvocationStat) InvocationStatDimension(com.alipay.sofa.rpc.client.aft.InvocationStatDimension) ArrayList(java.util.ArrayList)

Example 5 with InvocationStat

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());
}
Also used : InvocationStat(com.alipay.sofa.rpc.client.aft.InvocationStat) MeasureResultDetail(com.alipay.sofa.rpc.client.aft.MeasureResultDetail) MeasureModel(com.alipay.sofa.rpc.client.aft.MeasureModel)

Aggregations

InvocationStat (com.alipay.sofa.rpc.client.aft.InvocationStat)5 InvocationStatDimension (com.alipay.sofa.rpc.client.aft.InvocationStatDimension)2 MeasureResultDetail (com.alipay.sofa.rpc.client.aft.MeasureResultDetail)2 ArrayList (java.util.ArrayList)2 ProviderGroup (com.alipay.sofa.rpc.client.ProviderGroup)1 ProviderInfo (com.alipay.sofa.rpc.client.ProviderInfo)1 MeasureModel (com.alipay.sofa.rpc.client.aft.MeasureModel)1 MeasureResult (com.alipay.sofa.rpc.client.aft.MeasureResult)1 ConsumerConfig (com.alipay.sofa.rpc.config.ConsumerConfig)1 List (java.util.List)1