Browse Source

Fix the problem that requests will never be blocked when slowRatioThreshold = 100% (#1779)

master
Lynx GitHub 4 years ago
parent
commit
6f2f844726
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 1 deletions
  1. +6
    -1
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ResponseTimeCircuitBreaker.java
  2. +58
    -0
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ResponseTimeCircuitBreakerTest.java

+ 6
- 1
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ResponseTimeCircuitBreaker.java View File

@@ -19,7 +19,6 @@ import java.util.List;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.context.Context;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.statistic.base.LeapArray;
@@ -34,6 +33,8 @@ import com.alibaba.csp.sentinel.util.TimeUtil;
*/
public class ResponseTimeCircuitBreaker extends AbstractCircuitBreaker {

private static final double SLOW_REQUEST_RATIO_MAX_VALUE = 1.0d;

private final long maxAllowedRt;
private final double maxSlowRequestRatio;
private final int minRequestAmount;
@@ -110,6 +111,10 @@ public class ResponseTimeCircuitBreaker extends AbstractCircuitBreaker {
if (currentRatio > maxSlowRequestRatio) {
transformToOpen(currentRatio);
}
if (Double.compare(currentRatio, maxSlowRequestRatio) == 0 &&
Double.compare(maxSlowRequestRatio, SLOW_REQUEST_RATIO_MAX_VALUE) == 0) {
transformToOpen(currentRatio);
}
}

static class SlowRequestCounter {


+ 58
- 0
sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ResponseTimeCircuitBreakerTest.java View File

@@ -0,0 +1,58 @@
package com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker;

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
* @author xierz
* @date 2020/10/4
*/
public class ResponseTimeCircuitBreakerTest extends AbstractTimeBasedTest {
@Before
public void setUp() {
DegradeRuleManager.loadRules(new ArrayList<DegradeRule>());
}

@After
public void tearDown() throws Exception {
DegradeRuleManager.loadRules(new ArrayList<DegradeRule>());
}

@Test
public void testMaxSlowRatioThreshold() {
String resource = "testMaxSlowRatioThreshold";
DegradeRule rule = new DegradeRule("resource")
.setCount(10)
.setGrade(RuleConstant.DEGRADE_GRADE_RT)
.setMinRequestAmount(3)
.setSlowRatioThreshold(1)
.setStatIntervalMs(5000)
.setTimeWindow(5);
rule.setResource(resource);
DegradeRuleManager.loadRules(Collections.singletonList(rule));

assertTrue(entryAndSleepFor(resource, 20));
assertTrue(entryAndSleepFor(resource, 20));
assertTrue(entryAndSleepFor(resource, 20));

// should be blocked, cause 3/3 requests' rt is bigger than max rt.
assertFalse(entryAndSleepFor(resource,20));
sleep(1000);
assertFalse(entryAndSleepFor(resource,20));
sleep(4000);

assertTrue(entryAndSleepFor(resource, 20));
}

}

Loading…
Cancel
Save