Search in sources :

Example 16 with TokenResult

use of com.alibaba.csp.sentinel.cluster.TokenResult in project Sentinel by alibaba.

the class ConcurrentClusterFlowCheckerTest method testEasyAcquireAndRelease.

@Test
public void testEasyAcquireAndRelease() throws InterruptedException {
    setCurrentMillis(System.currentTimeMillis());
    FlowRule rule = ClusterFlowRuleManager.getFlowRuleById(111L);
    ArrayList<Long> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        TokenResult result = ConcurrentClusterFlowChecker.acquireConcurrentToken("127.0.0.1", rule, 1);
        Assert.assertTrue("fail to acquire token", result.getStatus() == TokenResultStatus.OK && result.getTokenId() != 0);
        list.add(result.getTokenId());
    }
    for (int i = 0; i < 10; i++) {
        TokenResult result = ConcurrentClusterFlowChecker.acquireConcurrentToken("127.0.0.1", rule, 1);
        Assert.assertTrue("fail to acquire block token", result.getStatus() == TokenResultStatus.BLOCKED);
    }
    for (int i = 0; i < 10; i++) {
        TokenResult result = ConcurrentClusterFlowChecker.releaseConcurrentToken(list.get(i));
        Assert.assertTrue("fail to release token", result.getStatus() == TokenResultStatus.RELEASE_OK);
    }
    Assert.assertTrue("fail to release token", CurrentConcurrencyManager.get(111L).get() == 0 && TokenCacheNodeManager.getSize() == 0);
}
Also used : TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult) ArrayList(java.util.ArrayList) FlowRule(com.alibaba.csp.sentinel.slots.block.flow.FlowRule) AbstractTimeBasedTest(com.alibaba.csp.sentinel.test.AbstractTimeBasedTest) Test(org.junit.Test)

Example 17 with TokenResult

use of com.alibaba.csp.sentinel.cluster.TokenResult in project Sentinel by alibaba.

the class DefaultClusterTokenClient method requestToken.

@Override
public TokenResult requestToken(Long flowId, int acquireCount, boolean prioritized) {
    if (notValidRequest(flowId, acquireCount)) {
        return badRequest();
    }
    FlowRequestData data = new FlowRequestData().setCount(acquireCount).setFlowId(flowId).setPriority(prioritized);
    ClusterRequest<FlowRequestData> request = new ClusterRequest<>(ClusterConstants.MSG_TYPE_FLOW, data);
    try {
        TokenResult result = sendTokenRequest(request);
        logForResult(result);
        return result;
    } catch (Exception ex) {
        ClusterClientStatLogUtil.log(ex.getMessage());
        return new TokenResult(TokenResultStatus.FAIL);
    }
}
Also used : TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult) ClusterRequest(com.alibaba.csp.sentinel.cluster.request.ClusterRequest) FlowRequestData(com.alibaba.csp.sentinel.cluster.request.data.FlowRequestData) ParamFlowRequestData(com.alibaba.csp.sentinel.cluster.request.data.ParamFlowRequestData)

Example 18 with TokenResult

use of com.alibaba.csp.sentinel.cluster.TokenResult 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 19 with TokenResult

use of com.alibaba.csp.sentinel.cluster.TokenResult in project Sentinel by alibaba.

the class ClusterParamFlowChecker method acquireClusterToken.

static TokenResult acquireClusterToken(ParamFlowRule rule, int count, Collection<Object> values) {
    Long id = rule.getClusterConfig().getFlowId();
    if (!allowProceed(id)) {
        return new TokenResult(TokenResultStatus.TOO_MANY_REQUEST);
    }
    ClusterParamMetric metric = ClusterParamMetricStatistics.getMetric(id);
    if (metric == null) {
        // Unexpected state, return FAIL.
        return new TokenResult(TokenResultStatus.FAIL);
    }
    if (values == null || values.isEmpty()) {
        // Empty parameter list will always pass.
        return new TokenResult(TokenResultStatus.OK);
    }
    double remaining = -1;
    boolean hasPassed = true;
    Object blockObject = null;
    for (Object value : values) {
        double latestQps = metric.getAvg(value);
        double threshold = calcGlobalThreshold(rule, value);
        double nextRemaining = threshold - latestQps - count;
        remaining = nextRemaining;
        if (nextRemaining < 0) {
            hasPassed = false;
            blockObject = value;
            break;
        }
    }
    if (hasPassed) {
        for (Object value : values) {
            metric.addValue(value, count);
        }
        ClusterServerStatLogUtil.log(String.format("param|pass|%d", id));
    } else {
        ClusterServerStatLogUtil.log(String.format("param|block|%d|%s", id, blockObject));
    }
    if (values.size() > 1) {
        // Remaining field is unsupported for multi-values.
        remaining = -1;
    }
    return hasPassed ? newPassResponse((int) remaining) : newBlockResponse();
}
Also used : TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult) ClusterParamMetric(com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterParamMetric)

Example 20 with TokenResult

use of com.alibaba.csp.sentinel.cluster.TokenResult in project Sentinel by alibaba.

the class ConcurrentClusterFlowChecker method acquireConcurrentToken.

public static TokenResult acquireConcurrentToken(/*@Valid*/
String clientAddress, FlowRule rule, int acquireCount) {
    long flowId = rule.getClusterConfig().getFlowId();
    AtomicInteger nowCalls = CurrentConcurrencyManager.get(flowId);
    if (nowCalls == null) {
        RecordLog.warn("[ConcurrentClusterFlowChecker] Fail to get nowCalls by flowId<{}>", flowId);
        return new TokenResult(TokenResultStatus.FAIL);
    }
    // check before enter the lock to improve the efficiency
    if (nowCalls.get() + acquireCount > calcGlobalThreshold(rule)) {
        ClusterServerStatLogUtil.log("concurrent|block|" + flowId, acquireCount);
        return new TokenResult(TokenResultStatus.BLOCKED);
    }
    // lock different nowCalls to improve the efficiency
    synchronized (nowCalls) {
        // check again whether the request can pass.
        if (nowCalls.get() + acquireCount > calcGlobalThreshold(rule)) {
            ClusterServerStatLogUtil.log("concurrent|block|" + flowId, acquireCount);
            return new TokenResult(TokenResultStatus.BLOCKED);
        } else {
            nowCalls.getAndAdd(acquireCount);
        }
    }
    ClusterServerStatLogUtil.log("concurrent|pass|" + flowId, acquireCount);
    TokenCacheNode node = TokenCacheNode.generateTokenCacheNode(rule, acquireCount, clientAddress);
    TokenCacheNodeManager.putTokenCacheNode(node.getTokenId(), node);
    TokenResult tokenResult = new TokenResult(TokenResultStatus.OK);
    tokenResult.setTokenId(node.getTokenId());
    return tokenResult;
}
Also used : TokenCacheNode(com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TokenResult(com.alibaba.csp.sentinel.cluster.TokenResult)

Aggregations

TokenResult (com.alibaba.csp.sentinel.cluster.TokenResult)22 FlowRule (com.alibaba.csp.sentinel.slots.block.flow.FlowRule)11 Test (org.junit.Test)6 TokenService (com.alibaba.csp.sentinel.cluster.TokenService)4 RateLimitDescriptor (io.envoyproxy.envoy.api.v2.ratelimit.RateLimitDescriptor)3 RateLimitDescriptor (io.envoyproxy.envoy.extensions.common.ratelimit.v3.RateLimitDescriptor)3 RateLimitResponse (io.envoyproxy.envoy.service.ratelimit.v2.RateLimitResponse)3 RateLimitResponse (io.envoyproxy.envoy.service.ratelimit.v3.RateLimitResponse)3 ArrayList (java.util.ArrayList)3 TokenResultStatus (com.alibaba.csp.sentinel.cluster.TokenResultStatus)2 TokenCacheNode (com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode)2 ClusterMetric (com.alibaba.csp.sentinel.cluster.flow.statistic.metric.ClusterMetric)2 ClusterRequest (com.alibaba.csp.sentinel.cluster.request.ClusterRequest)2 ParamFlowRequestData (com.alibaba.csp.sentinel.cluster.request.data.ParamFlowRequestData)2 AbstractTimeBasedTest (com.alibaba.csp.sentinel.test.AbstractTimeBasedTest)2 Tuple2 (com.alibaba.csp.sentinel.util.function.Tuple2)2 RateLimitRequest (io.envoyproxy.envoy.service.ratelimit.v2.RateLimitRequest)2 Code (io.envoyproxy.envoy.service.ratelimit.v2.RateLimitResponse.Code)2 RateLimitRequest (io.envoyproxy.envoy.service.ratelimit.v3.RateLimitRequest)2 StreamObserver (io.grpc.stub.StreamObserver)2