Search in sources :

Example 1 with ClusterMetric

use of com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric in project Sentinel by alibaba.

the class ClusterMetricNodeGenerator method flowToMetricNode.

public static ClusterMetricNode flowToMetricNode(long flowId) {
    FlowRule rule = ClusterFlowRuleManager.getFlowRuleById(flowId);
    if (rule == null) {
        return null;
    }
    ClusterMetric metric = ClusterMetricStatistics.getMetric(flowId);
    if (metric == null) {
        return new ClusterMetricNode().setFlowId(flowId).setResourceName(rule.getResource());
    }
    return new ClusterMetricNode().setFlowId(flowId).setResourceName(rule.getResource()).setBlockQps(metric.getAvg(ClusterFlowEvent.BLOCK)).setPassQps(metric.getAvg(ClusterFlowEvent.PASS)).setTimestamp(TimeUtil.currentTimeMillis());
}
Also used : ClusterMetric(com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric) ParamFlowRule(com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule)

Example 2 with ClusterMetric

use of com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric in project Sentinel by alibaba.

the class SimpleClusterFlowChecker method acquireClusterToken.

public static TokenResult acquireClusterToken(/*@Valid*/
FlowRule rule, int acquireCount) {
    Long id = rule.getClusterConfig().getFlowId();
    ClusterMetric metric = ClusterMetricStatistics.getMetric(id);
    if (metric == null) {
        return new TokenResult(TokenResultStatus.FAIL);
    }
    double latestQps = metric.getAvg(ClusterFlowEvent.PASS);
    double globalThreshold = rule.getCount() * ClusterServerConfigManager.getExceedCount();
    double nextRemaining = globalThreshold - latestQps - acquireCount;
    if (nextRemaining >= 0) {
        metric.add(ClusterFlowEvent.PASS, acquireCount);
        metric.add(ClusterFlowEvent.PASS_REQUEST, 1);
        ClusterServerStatLogUtil.log("flow|pass|" + id, acquireCount);
        ClusterServerStatLogUtil.log("flow|pass_request|" + id, 1);
        // Remaining count is cut down to a smaller integer.
        return new TokenResult(TokenResultStatus.OK).setRemaining((int) nextRemaining).setWaitInMs(0);
    } else {
        // Blocked.
        metric.add(ClusterFlowEvent.BLOCK, acquireCount);
        metric.add(ClusterFlowEvent.BLOCK_REQUEST, 1);
        ClusterServerStatLogUtil.log("flow|block|" + id, acquireCount);
        ClusterServerStatLogUtil.log("flow|block_request|" + id, 1);
        return blockedResult();
    }
}
Also used : ClusterMetric(com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric) TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult)

Example 3 with ClusterMetric

use of com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric in project Sentinel by alibaba.

the class ClusterFlowCheckerTest method testAcquireClusterTokenOccupyPass.

// @Test
public void testAcquireClusterTokenOccupyPass() {
    long flowId = 98765L;
    final int threshold = 5;
    FlowRule clusterRule = new FlowRule("abc").setCount(threshold).setClusterMode(true).setClusterConfig(new ClusterFlowConfig().setFlowId(flowId).setThresholdType(ClusterRuleConstant.FLOW_THRESHOLD_GLOBAL));
    int sampleCount = 5;
    int intervalInMs = 1000;
    int bucketLength = intervalInMs / sampleCount;
    ClusterMetric metric = new ClusterMetric(sampleCount, intervalInMs);
    ClusterMetricStatistics.putMetric(flowId, metric);
    System.out.println(System.currentTimeMillis());
    assertResultPass(tryAcquire(clusterRule, false));
    assertResultPass(tryAcquire(clusterRule, false));
    sleep(bucketLength);
    assertResultPass(tryAcquire(clusterRule, false));
    sleep(bucketLength);
    assertResultPass(tryAcquire(clusterRule, true));
    assertResultPass(tryAcquire(clusterRule, false));
    assertResultBlock(tryAcquire(clusterRule, true));
    sleep(bucketLength);
    assertResultBlock(tryAcquire(clusterRule, false));
    assertResultBlock(tryAcquire(clusterRule, false));
    sleep(bucketLength);
    assertResultBlock(tryAcquire(clusterRule, false));
    assertResultWait(tryAcquire(clusterRule, true), bucketLength);
    assertResultBlock(tryAcquire(clusterRule, false));
    sleep(bucketLength);
    assertResultPass(tryAcquire(clusterRule, false));
    ClusterMetricStatistics.removeMetric(flowId);
}
Also used : ClusterMetric(com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule) ClusterFlowConfig(com.alibaba.csp.sentinel.slots.block.flow.ClusterFlowConfig)

Example 4 with ClusterMetric

use of com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric in project Sentinel by alibaba.

the class ClusterFlowChecker method acquireClusterToken.

static TokenResult acquireClusterToken(/*@Valid*/
FlowRule rule, int acquireCount, boolean prioritized) {
    Long id = rule.getClusterConfig().getFlowId();
    if (!allowProceed(id)) {
        return new TokenResult(TokenResultStatus.TOO_MANY_REQUEST);
    }
    ClusterMetric metric = ClusterMetricStatistics.getMetric(id);
    if (metric == null) {
        return new TokenResult(TokenResultStatus.FAIL);
    }
    double latestQps = metric.getAvg(ClusterFlowEvent.PASS);
    double globalThreshold = calcGlobalThreshold(rule) * ClusterServerConfigManager.getExceedCount();
    double nextRemaining = globalThreshold - latestQps - acquireCount;
    if (nextRemaining >= 0) {
        // TODO: checking logic and metric operation should be separated.
        metric.add(ClusterFlowEvent.PASS, acquireCount);
        metric.add(ClusterFlowEvent.PASS_REQUEST, 1);
        if (prioritized) {
            // Add prioritized pass.
            metric.add(ClusterFlowEvent.OCCUPIED_PASS, acquireCount);
        }
        // Remaining count is cut down to a smaller integer.
        return new TokenResult(TokenResultStatus.OK).setRemaining((int) nextRemaining).setWaitInMs(0);
    } else {
        if (prioritized) {
            // Try to occupy incoming buckets.
            double occupyAvg = metric.getAvg(ClusterFlowEvent.WAITING);
            if (occupyAvg <= ClusterServerConfigManager.getMaxOccupyRatio() * globalThreshold) {
                int waitInMs = metric.tryOccupyNext(ClusterFlowEvent.PASS, acquireCount, globalThreshold);
                // waitInMs > 0 indicates pre-occupy incoming buckets successfully.
                if (waitInMs > 0) {
                    ClusterServerStatLogUtil.log("flow|waiting|" + id);
                    return new TokenResult(TokenResultStatus.SHOULD_WAIT).setRemaining(0).setWaitInMs(waitInMs);
                }
            // Or else occupy failed, should be blocked.
            }
        }
        // Blocked.
        metric.add(ClusterFlowEvent.BLOCK, acquireCount);
        metric.add(ClusterFlowEvent.BLOCK_REQUEST, 1);
        ClusterServerStatLogUtil.log("flow|block|" + id, acquireCount);
        ClusterServerStatLogUtil.log("flow|block_request|" + id, 1);
        if (prioritized) {
            // Add prioritized block.
            metric.add(ClusterFlowEvent.OCCUPIED_BLOCK, acquireCount);
            ClusterServerStatLogUtil.log("flow|occupied_block|" + id, 1);
        }
        return blockedResult();
    }
}
Also used : ClusterMetric(com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric) TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult)

Example 5 with ClusterMetric

use of com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric in project Sentinel by alibaba.

the class ClusterFlowRuleManager method applyClusterFlowRule.

private static void applyClusterFlowRule(List<FlowRule> list, /*@Valid*/
String namespace) {
    if (list == null || list.isEmpty()) {
        clearAndResetRulesFor(namespace);
        return;
    }
    final ConcurrentHashMap<Long, FlowRule> ruleMap = new ConcurrentHashMap<>();
    Set<Long> flowIdSet = new HashSet<>();
    for (FlowRule rule : list) {
        if (!rule.isClusterMode()) {
            continue;
        }
        if (!FlowRuleUtil.isValidRule(rule)) {
            RecordLog.warn("[ClusterFlowRuleManager] Ignoring invalid flow rule when loading new flow rules: " + rule);
            continue;
        }
        if (StringUtil.isBlank(rule.getLimitApp())) {
            rule.setLimitApp(RuleConstant.LIMIT_APP_DEFAULT);
        }
        // Flow id should not be null after filtered.
        ClusterFlowConfig clusterConfig = rule.getClusterConfig();
        Long flowId = clusterConfig.getFlowId();
        if (flowId == null) {
            continue;
        }
        ruleMap.put(flowId, rule);
        FLOW_NAMESPACE_MAP.put(flowId, namespace);
        flowIdSet.add(flowId);
        if (!CurrentConcurrencyManager.containsFlowId(flowId)) {
            CurrentConcurrencyManager.put(flowId, 0);
        }
        // Prepare cluster metric from valid flow ID.
        ClusterMetricStatistics.putMetricIfAbsent(flowId, new ClusterMetric(clusterConfig.getSampleCount(), clusterConfig.getWindowIntervalMs()));
    }
    // Cleanup unused cluster metrics.
    clearAndResetRulesConditional(namespace, new Predicate<Long>() {

        @Override
        public boolean test(Long flowId) {
            return !ruleMap.containsKey(flowId);
        }
    });
    FLOW_RULES.putAll(ruleMap);
    NAMESPACE_FLOW_ID_MAP.put(namespace, flowIdSet);
}
Also used : ClusterMetric(com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ClusterFlowConfig(com.alibaba.csp.sentinel.slots.block.flow.ClusterFlowConfig)

Aggregations

ClusterMetric (com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric)5 FlowRule (com.alibaba.csp.sentinel.slots.block.flow.FlowRule)3 TokenResult (com.alibaba.csp.sentinel.cluster.TokenResult)2 ClusterFlowConfig (com.alibaba.csp.sentinel.slots.block.flow.ClusterFlowConfig)2 ParamFlowRule (com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1