@@ -19,7 +19,6 @@ import java.util.List; | |||||
import com.alibaba.csp.sentinel.Entry; | import com.alibaba.csp.sentinel.Entry; | ||||
import com.alibaba.csp.sentinel.context.Context; | 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.RuleConstant; | ||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; | import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; | ||||
import com.alibaba.csp.sentinel.slots.statistic.base.LeapArray; | 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 { | public class ResponseTimeCircuitBreaker extends AbstractCircuitBreaker { | ||||
private static final double SLOW_REQUEST_RATIO_MAX_VALUE = 1.0d; | |||||
private final long maxAllowedRt; | private final long maxAllowedRt; | ||||
private final double maxSlowRequestRatio; | private final double maxSlowRequestRatio; | ||||
private final int minRequestAmount; | private final int minRequestAmount; | ||||
@@ -110,6 +111,10 @@ public class ResponseTimeCircuitBreaker extends AbstractCircuitBreaker { | |||||
if (currentRatio > maxSlowRequestRatio) { | if (currentRatio > maxSlowRequestRatio) { | ||||
transformToOpen(currentRatio); | transformToOpen(currentRatio); | ||||
} | } | ||||
if (Double.compare(currentRatio, maxSlowRequestRatio) == 0 && | |||||
Double.compare(maxSlowRequestRatio, SLOW_REQUEST_RATIO_MAX_VALUE) == 0) { | |||||
transformToOpen(currentRatio); | |||||
} | |||||
} | } | ||||
static class SlowRequestCounter { | static class SlowRequestCounter { | ||||
@@ -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)); | |||||
} | |||||
} |