Browse Source

Refactor Node interface: change return type of `xxxQps` method from long to double (#564)

- Update test cases (use assertEquals(e, a, delta) instead)
- Also add `totalPass` method in Node interface

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
master
Eric Zhao GitHub 5 years ago
parent
commit
4b1ccd93e2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 200 additions and 127 deletions
  1. +1
    -1
      sentinel-adapter/sentinel-reactor-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/reactor/FluxSentinelOperatorTestIntegrationTest.java
  2. +2
    -2
      sentinel-adapter/sentinel-spring-webflux-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/spring/webflux/SentinelWebFluxIntegrationTest.java
  3. +3
    -3
      sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilterTest.java
  4. +4
    -6
      sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletmethod/CommonFilterMethodTest.java
  5. +3
    -3
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/DefaultNode.java
  6. +19
    -11
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/EntranceNode.java
  7. +49
    -23
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/Node.java
  8. +20
    -15
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/StatisticNode.java
  9. +1
    -1
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/DegradeRule.java
  10. +2
    -2
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpController.java
  11. +7
    -11
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpRateLimiterController.java
  12. +28
    -0
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/metric/DebugSupport.java
  13. +3
    -3
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/ClusterNodeTest.java
  14. +4
    -4
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/StatisticNodeTest.java
  15. +5
    -5
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/DegradeTest.java
  16. +13
    -0
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/FlowPartialIntegrationTest.java
  17. +11
    -12
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/FlowRuleTest.java
  18. +1
    -1
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/controller/DefaultControllerTest.java
  19. +7
    -7
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpControllerTest.java
  20. +5
    -5
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpRateLimiterControllerTest.java
  21. +12
    -12
      sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/vo/NodeVo.java

+ 1
- 1
sentinel-adapter/sentinel-reactor-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/reactor/FluxSentinelOperatorTestIntegrationTest.java View File

@@ -45,7 +45,7 @@ public class FluxSentinelOperatorTestIntegrationTest {


ClusterNode cn = ClusterBuilderSlot.getClusterNode(resourceName); ClusterNode cn = ClusterBuilderSlot.getClusterNode(resourceName);
assertNotNull(cn); assertNotNull(cn);
assertEquals(1, cn.passQps());
assertEquals(1, cn.passQps(), 0.01);
assertEquals(1, cn.totalException()); assertEquals(1, cn.totalException());
} }




+ 2
- 2
sentinel-adapter/sentinel-spring-webflux-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/spring/webflux/SentinelWebFluxIntegrationTest.java View File

@@ -68,7 +68,7 @@ public class SentinelWebFluxIntegrationTest {


ClusterNode cn = ClusterBuilderSlot.getClusterNode(url); ClusterNode cn = ClusterBuilderSlot.getClusterNode(url);
assertNotNull(cn); assertNotNull(cn);
assertEquals(1, cn.passQps());
assertEquals(1, cn.passQps(), 0.01);
} }


@Test @Test
@@ -94,7 +94,7 @@ public class SentinelWebFluxIntegrationTest {
.expectBody(String.class).isEqualTo("Hello 2"); .expectBody(String.class).isEqualTo("Hello 2");


ClusterNode cn = ClusterBuilderSlot.getClusterNode(fooPrefix + "*"); ClusterNode cn = ClusterBuilderSlot.getClusterNode(fooPrefix + "*");
assertEquals(2, cn.passQps());
assertEquals(2, cn.passQps(), 0.01);
assertNull(ClusterBuilderSlot.getClusterNode(url1)); assertNull(ClusterBuilderSlot.getClusterNode(url1));
assertNull(ClusterBuilderSlot.getClusterNode(url2)); assertNull(ClusterBuilderSlot.getClusterNode(url2));




+ 3
- 3
sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilterTest.java View File

@@ -83,7 +83,7 @@ public class CommonFilterTest {


ClusterNode cn = ClusterBuilderSlot.getClusterNode(url); ClusterNode cn = ClusterBuilderSlot.getClusterNode(url);
assertNotNull(cn); assertNotNull(cn);
assertEquals(1, cn.passQps());
assertEquals(1, cn.passQps(), 0.01);


testCommonBlockAndRedirectBlockPage(url, cn); testCommonBlockAndRedirectBlockPage(url, cn);


@@ -99,7 +99,7 @@ public class CommonFilterTest {
this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN)) this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().string(FilterUtil.DEFAULT_BLOCK_MSG)); .andExpect(content().string(FilterUtil.DEFAULT_BLOCK_MSG));
assertEquals(1, cn.blockQps());
assertEquals(1, cn.blockQps(), 0.01);


// Test for redirect. // Test for redirect.
String redirectUrl = "http://some-location.com"; String redirectUrl = "http://some-location.com";
@@ -132,7 +132,7 @@ public class CommonFilterTest {
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().string("Hello 2")); .andExpect(content().string("Hello 2"));
ClusterNode cn = ClusterBuilderSlot.getClusterNode(fooPrefix + "*"); ClusterNode cn = ClusterBuilderSlot.getClusterNode(fooPrefix + "*");
assertEquals(2, cn.passQps());
assertEquals(2, cn.passQps(), 0.01);
assertNull(ClusterBuilderSlot.getClusterNode(url1)); assertNull(ClusterBuilderSlot.getClusterNode(url1));
assertNull(ClusterBuilderSlot.getClusterNode(url2)); assertNull(ClusterBuilderSlot.getClusterNode(url2));




+ 4
- 6
sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletmethod/CommonFilterMethodTest.java View File

@@ -86,7 +86,7 @@ public class CommonFilterMethodTest {


ClusterNode cnGet = ClusterBuilderSlot.getClusterNode(GET + COLON + url); ClusterNode cnGet = ClusterBuilderSlot.getClusterNode(GET + COLON + url);
assertNotNull(cnGet); assertNotNull(cnGet);
assertEquals(1, cnGet.passQps());
assertEquals(1, cnGet.passQps(), 0.01);




ClusterNode cnPost = ClusterBuilderSlot.getClusterNode(POST + COLON + url); ClusterNode cnPost = ClusterBuilderSlot.getClusterNode(POST + COLON + url);
@@ -98,10 +98,9 @@ public class CommonFilterMethodTest {


cnPost = ClusterBuilderSlot.getClusterNode(POST + COLON + url); cnPost = ClusterBuilderSlot.getClusterNode(POST + COLON + url);
assertNotNull(cnPost); assertNotNull(cnPost);
assertEquals(1, cnPost.passQps());
assertEquals(1, cnPost.passQps(), 0.01);


testCommonBlockAndRedirectBlockPage(url, cnGet, cnPost); testCommonBlockAndRedirectBlockPage(url, cnGet, cnPost);

} }


private void testCommonBlockAndRedirectBlockPage(String url, ClusterNode cnGet, ClusterNode cnPost) throws Exception { private void testCommonBlockAndRedirectBlockPage(String url, ClusterNode cnGet, ClusterNode cnPost) throws Exception {
@@ -110,21 +109,20 @@ public class CommonFilterMethodTest {
this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN)) this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().string(FilterUtil.DEFAULT_BLOCK_MSG)); .andExpect(content().string(FilterUtil.DEFAULT_BLOCK_MSG));
assertEquals(1, cnGet.blockQps());
assertEquals(1, cnGet.blockQps(), 0.01);


// Test for post pass // Test for post pass
this.mvc.perform(post(url)) this.mvc.perform(post(url))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().string(HELLO_POST_STR)); .andExpect(content().string(HELLO_POST_STR));


assertEquals(2, cnPost.passQps());
assertEquals(2, cnPost.passQps(), 0.01);




FlowRuleManager.loadRules(null); FlowRuleManager.loadRules(null);
WebServletConfig.setBlockPage(""); WebServletConfig.setBlockPage("");
} }



@After @After
public void cleanUp() { public void cleanUp() {
FlowRuleManager.loadRules(null); FlowRuleManager.loadRules(null);


+ 3
- 3
sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/DefaultNode.java View File

@@ -48,7 +48,7 @@ public class DefaultNode extends StatisticNode {
/** /**
* The list of all child nodes. * The list of all child nodes.
*/ */
private volatile Set<Node> childList = new HashSet<Node>();
private volatile Set<Node> childList = new HashSet<>();


/** /**
* Associated cluster node. * Associated cluster node.
@@ -85,7 +85,7 @@ public class DefaultNode extends StatisticNode {
if (!childList.contains(node)) { if (!childList.contains(node)) {
synchronized (this) { synchronized (this) {
if (!childList.contains(node)) { if (!childList.contains(node)) {
Set<Node> newSet = new HashSet<Node>(childList.size() + 1);
Set<Node> newSet = new HashSet<>(childList.size() + 1);
newSet.addAll(childList); newSet.addAll(childList);
newSet.add(node); newSet.add(node);
childList = newSet; childList = newSet;
@@ -99,7 +99,7 @@ public class DefaultNode extends StatisticNode {
* Reset the child node list. * Reset the child node list.
*/ */
public void removeChildList() { public void removeChildList() {
this.childList = new HashSet<Node>();
this.childList = new HashSet<>();
} }


public Set<Node> getChildList() { public Set<Node> getChildList() {


+ 19
- 11
sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/EntranceNode.java View File

@@ -43,9 +43,9 @@ public class EntranceNode extends DefaultNode {
} }


@Override @Override
public long avgRt() {
long total = 0;
long totalQps = 0;
public double avgRt() {
double total = 0;
double totalQps = 0;
for (Node node : getChildList()) { for (Node node : getChildList()) {
total += node.avgRt() * node.passQps(); total += node.avgRt() * node.passQps();
totalQps += node.passQps(); totalQps += node.passQps();
@@ -54,8 +54,8 @@ public class EntranceNode extends DefaultNode {
} }


@Override @Override
public long blockQps() {
long blockQps = 0;
public double blockQps() {
double blockQps = 0;
for (Node node : getChildList()) { for (Node node : getChildList()) {
blockQps += node.blockQps(); blockQps += node.blockQps();
} }
@@ -81,8 +81,8 @@ public class EntranceNode extends DefaultNode {
} }


@Override @Override
public long totalQps() {
long r = 0;
public double totalQps() {
double r = 0;
for (Node node : getChildList()) { for (Node node : getChildList()) {
r += node.totalQps(); r += node.totalQps();
} }
@@ -90,8 +90,8 @@ public class EntranceNode extends DefaultNode {
} }


@Override @Override
public long successQps() {
long r = 0;
public double successQps() {
double r = 0;
for (Node node : getChildList()) { for (Node node : getChildList()) {
r += node.successQps(); r += node.successQps();
} }
@@ -99,8 +99,8 @@ public class EntranceNode extends DefaultNode {
} }


@Override @Override
public long passQps() {
long r = 0;
public double passQps() {
double r = 0;
for (Node node : getChildList()) { for (Node node : getChildList()) {
r += node.passQps(); r += node.passQps();
} }
@@ -116,4 +116,12 @@ public class EntranceNode extends DefaultNode {
return r; return r;
} }


@Override
public long totalPass() {
long r = 0;
for (Node node : getChildList()) {
r += node.totalPass();
}
return r;
}
} }

+ 49
- 23
sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/Node.java View File

@@ -19,98 +19,125 @@ import java.util.Map;


import com.alibaba.csp.sentinel.Entry; import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.node.metric.MetricNode; import com.alibaba.csp.sentinel.node.metric.MetricNode;
import com.alibaba.csp.sentinel.slots.statistic.metric.DebugSupport;


/** /**
* This class holds real-time statistics for a resource.
* Holds real-time statistics for resources.
* *
* @author qinan.qn * @author qinan.qn
* @author leyou * @author leyou
* @author Eric Zhao * @author Eric Zhao
*/ */
public interface Node {
public interface Node extends DebugSupport {


/** /**
* Get incoming request per minute. {@code pass + block}
* Get incoming request per minute ({@code pass + block}).
*
* @return total request count per minute
*/ */
long totalRequest(); long totalRequest();


/**
* Get pass count per minute.
*
* @return total passed request count per minute
* @since 1.5.0
*/
long totalPass();

/** /**
* Get {@link Entry#exit()} count per minute. * Get {@link Entry#exit()} count per minute.
* *
* @return Outgoing request per minute.
* @return total completed request count per minute
*/ */
long totalSuccess(); long totalSuccess();


/** /**
* Get block request count per minute.
* Get blocked request count per minute (totalBlockRequest).
*
* @return total blocked request count per minute
*/ */
long blockRequest(); long blockRequest();


/** /**
* Get exception count per minute. * Get exception count per minute.
*
* @return total business exception count per minute
*/ */
long totalException(); long totalException();


/** /**
* Get pass request per second. * Get pass request per second.
*
* @return QPS of passed requests
*/ */
long passQps();
double passQps();


/** /**
* Get block request per second. * Get block request per second.
*
* @return QPS of blocked requests
*/ */
long blockQps();
double blockQps();


/** /**
* Get {@link #passQps()} + {@link #blockQps()} request per second. * Get {@link #passQps()} + {@link #blockQps()} request per second.
*
* @return QPS of passed and blocked requests
*/ */
long totalQps();
double totalQps();


/** /**
* Get {@link Entry#exit()} request per second. * Get {@link Entry#exit()} request per second.
*
* @return QPS of completed requests
*/ */
long successQps();
double successQps();


/** /**
* Get estimated max success QPS till now. * Get estimated max success QPS till now.
* *
* @return max success QPS
* @return max completed QPS
*/ */
long maxSuccessQps();
double maxSuccessQps();


/** /**
* Get exception count per second. * Get exception count per second.
*
* @return QPS of exception occurs
*/ */
long exceptionQps();
double exceptionQps();


/** /**
* Get average rt per second. * Get average rt per second.
* *
* @return average response time per second * @return average response time per second
*/ */
long avgRt();
double avgRt();


/** /**
* Get minimal response time. * Get minimal response time.
* *
* @return recorded minimal response time * @return recorded minimal response time
*/ */
long minRt();
double minRt();


/** /**
* Get current active thread count. * Get current active thread count.
*
* @return current active thread count
*/ */
int curThreadNum(); int curThreadNum();


/** /**
* Get last second block QPS. * Get last second block QPS.
*/ */
long previousBlockQps();
double previousBlockQps();


/** /**
* Last window QPS. * Last window QPS.
*/ */
long previousPassQps();
double previousPassQps();


/** /**
* Fetch all valid metric nodes of resources. * Fetch all valid metric nodes of resources.
@@ -129,18 +156,22 @@ public interface Node {
/** /**
* Add rt and success count. * Add rt and success count.
* *
* @param rt response time
* @param rt response time
* @param success success count to add * @param success success count to add
*/ */
void addRtAndSuccess(long rt, int success); void addRtAndSuccess(long rt, int success);


/** /**
* Increase the block count. * Increase the block count.
*
* @param count count to add
*/ */
void increaseBlockQps(int count); void increaseBlockQps(int count);


/** /**
* Increase the biz exception count.
* Add the biz exception count.
*
* @param count count to add
*/ */
void increaseExceptionQps(int count); void increaseExceptionQps(int count);


@@ -159,9 +190,4 @@ public interface Node {
* {@link SampleCountProperty#SAMPLE_COUNT} is changed. * {@link SampleCountProperty#SAMPLE_COUNT} is changed.
*/ */
void reset(); void reset();

/**
* Debug only.
*/
void debug();
} }

+ 20
- 15
sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/StatisticNode.java View File

@@ -151,28 +151,33 @@ public class StatisticNode implements Node {
return totalRequest; return totalRequest;
} }


@Override
public long totalPass() {
return rollingCounterInMinute.pass();
}

@Override @Override
public long blockRequest() { public long blockRequest() {
return rollingCounterInMinute.block(); return rollingCounterInMinute.block();
} }


@Override @Override
public long blockQps() {
return rollingCounterInSecond.block() / (long) rollingCounterInSecond.getWindowIntervalInSec();
public double blockQps() {
return rollingCounterInSecond.block() / rollingCounterInSecond.getWindowIntervalInSec();
} }


@Override @Override
public long previousBlockQps() {
public double previousBlockQps() {
return this.rollingCounterInMinute.previousWindowBlock(); return this.rollingCounterInMinute.previousWindowBlock();
} }


@Override @Override
public long previousPassQps() {
public double previousPassQps() {
return this.rollingCounterInMinute.previousWindowPass(); return this.rollingCounterInMinute.previousWindowPass();
} }


@Override @Override
public long totalQps() {
public double totalQps() {
return passQps() + blockQps(); return passQps() + blockQps();
} }


@@ -182,8 +187,8 @@ public class StatisticNode implements Node {
} }


@Override @Override
public long exceptionQps() {
return rollingCounterInSecond.exception() / (long) rollingCounterInSecond.getWindowIntervalInSec();
public double exceptionQps() {
return rollingCounterInSecond.exception() / rollingCounterInSecond.getWindowIntervalInSec();
} }


@Override @Override
@@ -192,32 +197,32 @@ public class StatisticNode implements Node {
} }


@Override @Override
public long passQps() {
return rollingCounterInSecond.pass() / (long) rollingCounterInSecond.getWindowIntervalInSec();
public double passQps() {
return rollingCounterInSecond.pass() / rollingCounterInSecond.getWindowIntervalInSec();
} }


@Override @Override
public long successQps() {
return rollingCounterInSecond.success() / (long) rollingCounterInSecond.getWindowIntervalInSec();
public double successQps() {
return rollingCounterInSecond.success() / rollingCounterInSecond.getWindowIntervalInSec();
} }


@Override @Override
public long maxSuccessQps() {
public double maxSuccessQps() {
return rollingCounterInSecond.maxSuccess() * rollingCounterInSecond.getSampleCount(); return rollingCounterInSecond.maxSuccess() * rollingCounterInSecond.getSampleCount();
} }


@Override @Override
public long avgRt() {
public double avgRt() {
long successCount = rollingCounterInSecond.success(); long successCount = rollingCounterInSecond.success();
if (successCount == 0) { if (successCount == 0) {
return 0; return 0;
} }


return rollingCounterInSecond.rt() / successCount;
return rollingCounterInSecond.rt() * 1.0 / successCount;
} }


@Override @Override
public long minRt() {
public double minRt() {
return rollingCounterInSecond.minRt(); return rollingCounterInSecond.minRt();
} }




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

@@ -184,7 +184,7 @@ public class DegradeRule extends AbstractRule {
} else if (grade == RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) { } else if (grade == RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) {
double exception = clusterNode.exceptionQps(); double exception = clusterNode.exceptionQps();
double success = clusterNode.successQps(); double success = clusterNode.successQps();
long total = clusterNode.totalQps();
double total = clusterNode.totalQps();
// if total qps less than RT_MAX_EXCEED_N, pass. // if total qps less than RT_MAX_EXCEED_N, pass.
if (total < RT_MAX_EXCEED_N) { if (total < RT_MAX_EXCEED_N) {
return true; return true;


+ 2
- 2
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpController.java View File

@@ -112,9 +112,9 @@ public class WarmUpController implements TrafficShapingController {


@Override @Override
public boolean canPass(Node node, int acquireCount, boolean prioritized) { public boolean canPass(Node node, int acquireCount, boolean prioritized) {
long passQps = node.passQps();
long passQps = (long) node.passQps();


long previousQps = node.previousPassQps();
long previousQps = (long) node.previousPassQps();
syncToken(previousQps); syncToken(previousQps);


// 开始计算它的斜率 // 开始计算它的斜率


+ 7
- 11
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpRateLimiterController.java View File

@@ -22,19 +22,16 @@ import com.alibaba.csp.sentinel.util.TimeUtil;


/** /**
* @author jialiang.linjl * @author jialiang.linjl
* @since 1.4.0
*/ */
public class WarmUpRateLimiterController extends WarmUpController { public class WarmUpRateLimiterController extends WarmUpController {


final int timeOutInMs;
final AtomicLong latestPassedTime = new AtomicLong(-1);
private final int timeoutInMs;
private final AtomicLong latestPassedTime = new AtomicLong(-1);


/**
* @param count
* @param warmUpPeriodSec
*/
public WarmUpRateLimiterController(double count, int warmUpPeriodSec, int timeOutMs, int coldFactor) { public WarmUpRateLimiterController(double count, int warmUpPeriodSec, int timeOutMs, int coldFactor) {
super(count, warmUpPeriodSec, coldFactor); super(count, warmUpPeriodSec, coldFactor);
this.timeOutInMs = timeOutMs;
this.timeoutInMs = timeOutMs;
} }


@Override @Override
@@ -44,7 +41,7 @@ public class WarmUpRateLimiterController extends WarmUpController {


@Override @Override
public boolean canPass(Node node, int acquireCount, boolean prioritized) { public boolean canPass(Node node, int acquireCount, boolean prioritized) {
long previousQps = node.previousPassQps();
long previousQps = (long) node.previousPassQps();
syncToken(previousQps); syncToken(previousQps);


long currentTime = TimeUtil.currentTimeMillis(); long currentTime = TimeUtil.currentTimeMillis();
@@ -68,13 +65,13 @@ public class WarmUpRateLimiterController extends WarmUpController {
return true; return true;
} else { } else {
long waitTime = costTime + latestPassedTime.get() - currentTime; long waitTime = costTime + latestPassedTime.get() - currentTime;
if (waitTime > timeOutInMs) {
if (waitTime > timeoutInMs) {
return false; return false;
} else { } else {
long oldTime = latestPassedTime.addAndGet(costTime); long oldTime = latestPassedTime.addAndGet(costTime);
try { try {
waitTime = oldTime - TimeUtil.currentTimeMillis(); waitTime = oldTime - TimeUtil.currentTimeMillis();
if (waitTime > timeOutInMs) {
if (waitTime > timeoutInMs) {
latestPassedTime.addAndGet(-costTime); latestPassedTime.addAndGet(-costTime);
return false; return false;
} }
@@ -89,4 +86,3 @@ public class WarmUpRateLimiterController extends WarmUpController {
return false; return false;
} }
} }


+ 28
- 0
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/metric/DebugSupport.java View File

@@ -0,0 +1,28 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.slots.statistic.metric;

/**
* @author Eric Zhao
* @since 1.5.0
*/
public interface DebugSupport {

/**
* For debug;
*/
void debug();
}

+ 3
- 3
sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/ClusterNodeTest.java View File

@@ -139,18 +139,18 @@ public class ClusterNodeTest {
// test count<=0, no exceptionQps added // test count<=0, no exceptionQps added
clusterNode.trace(exception, 0); clusterNode.trace(exception, 0);
clusterNode.trace(exception, -1); clusterNode.trace(exception, -1);
assertEquals(0, clusterNode.exceptionQps());
assertEquals(0, clusterNode.exceptionQps(), 0.01);
assertEquals(0, clusterNode.totalException()); assertEquals(0, clusterNode.totalException());


// test count=1, not BlockException, 1 exceptionQps added // test count=1, not BlockException, 1 exceptionQps added
clusterNode.trace(exception, 1); clusterNode.trace(exception, 1);
assertEquals(1, clusterNode.exceptionQps());
assertEquals(1, clusterNode.exceptionQps(), 0.01);
assertEquals(1, clusterNode.totalException()); assertEquals(1, clusterNode.totalException());


// test count=1, BlockException, no exceptionQps added // test count=1, BlockException, no exceptionQps added
FlowException flowException = new FlowException("flow"); FlowException flowException = new FlowException("flow");
clusterNode.trace(flowException, 1); clusterNode.trace(flowException, 1);
assertEquals(1, clusterNode.exceptionQps());
assertEquals(1, clusterNode.exceptionQps(), 0.01);
assertEquals(1, clusterNode.totalException()); assertEquals(1, clusterNode.totalException());
} }
} }

+ 4
- 4
sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/StatisticNodeTest.java View File

@@ -92,9 +92,9 @@ public class StatisticNodeTest {
tickEs.shutdown(); tickEs.shutdown();


// now no biz method execute, so there is no curThreadNum,passQps,successQps // now no biz method execute, so there is no curThreadNum,passQps,successQps
assertEquals(0, node.curThreadNum());
assertEquals(0, node.passQps());
assertEquals(0, node.successQps());
assertEquals(0, node.curThreadNum(), 0.01);
assertEquals(0, node.passQps(), 0.01);
assertEquals(0, node.successQps(), 0.01);


// note: total time cost should be controlled within 1 minute, // note: total time cost should be controlled within 1 minute,
// as the node.totalRequest() holding statistics of recent 60 seconds // as the node.totalRequest() holding statistics of recent 60 seconds
@@ -105,7 +105,7 @@ public class StatisticNodeTest {
assertEquals(totalRequest, node.totalSuccess()); assertEquals(totalRequest, node.totalSuccess());


// now there are no data in time span, so the minRT should be equals to TIME_DROP_VALVE // now there are no data in time span, so the minRT should be equals to TIME_DROP_VALVE
assertEquals(node.minRt(), Constants.TIME_DROP_VALVE);
assertEquals(node.minRt(), Constants.TIME_DROP_VALVE, 0.01);


log("===================================================="); log("====================================================");
log("testStatisticThreadNumAndQps done, cost " + (TimeUtil.currentTimeMillis() - testStartTime) + "ms"); log("testStatisticThreadNumAndQps done, cost " + (TimeUtil.currentTimeMillis() - testStartTime) + "ms");


+ 5
- 5
sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/DegradeTest.java View File

@@ -45,7 +45,7 @@ public class DegradeTest {
Context context = mock(Context.class); Context context = mock(Context.class);
DefaultNode node = mock(DefaultNode.class); DefaultNode node = mock(DefaultNode.class);
when(node.getClusterNode()).thenReturn(cn); when(node.getClusterNode()).thenReturn(cn);
when(cn.avgRt()).thenReturn(2L);
when(cn.avgRt()).thenReturn(2d);


DegradeRule rule = new DegradeRule(); DegradeRule rule = new DegradeRule();
rule.setCount(1); rule.setCount(1);
@@ -69,9 +69,9 @@ public class DegradeTest {
public void testExceptionRatioModeDegrade() throws Throwable { public void testExceptionRatioModeDegrade() throws Throwable {
String key = "test_degrade_exception_ratio"; String key = "test_degrade_exception_ratio";
ClusterNode cn = mock(ClusterNode.class); ClusterNode cn = mock(ClusterNode.class);
when(cn.exceptionQps()).thenReturn(2L);
when(cn.exceptionQps()).thenReturn(2d);
// Indicates that there are QPS more than min threshold. // Indicates that there are QPS more than min threshold.
when(cn.totalQps()).thenReturn(12L);
when(cn.totalQps()).thenReturn(12d);
ClusterBuilderSlot.getClusterNodeMap().put(new StringResourceWrapper(key, EntryType.IN), cn); ClusterBuilderSlot.getClusterNodeMap().put(new StringResourceWrapper(key, EntryType.IN), cn);


Context context = mock(Context.class); Context context = mock(Context.class);
@@ -84,7 +84,7 @@ public class DegradeTest {
rule.setTimeWindow(2); rule.setTimeWindow(2);
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO); rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);


when(cn.successQps()).thenReturn(8L);
when(cn.successQps()).thenReturn(8d);


// Will fail. // Will fail.
assertFalse(rule.passCheck(context, node, 1)); assertFalse(rule.passCheck(context, node, 1));
@@ -92,7 +92,7 @@ public class DegradeTest {
// Restore from the degrade timeout. // Restore from the degrade timeout.
TimeUnit.MILLISECONDS.sleep(2200); TimeUnit.MILLISECONDS.sleep(2200);


when(cn.successQps()).thenReturn(20L);
when(cn.successQps()).thenReturn(20d);
// Will pass. // Will pass.
assertTrue(rule.passCheck(context, node, 1)); assertTrue(rule.passCheck(context, node, 1));
} }


+ 13
- 0
sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/FlowPartialIntegrationTest.java View File

@@ -18,9 +18,12 @@ package com.alibaba.csp.sentinel.slots.block.flow;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;


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


import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;


import com.alibaba.csp.sentinel.Entry; import com.alibaba.csp.sentinel.Entry;
@@ -34,6 +37,16 @@ import com.alibaba.csp.sentinel.slots.block.RuleConstant;
*/ */
public class FlowPartialIntegrationTest { public class FlowPartialIntegrationTest {


@Before
public void setUp() throws Exception {
FlowRuleManager.loadRules(new ArrayList<FlowRule>());
}

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

@Test @Test
public void testQPSGrade() { public void testQPSGrade() {
FlowRule flowRule = new FlowRule(); FlowRule flowRule = new FlowRule();


+ 11
- 12
sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/FlowRuleTest.java View File

@@ -15,7 +15,7 @@
*/ */
package com.alibaba.csp.sentinel.slots.block.flow; package com.alibaba.csp.sentinel.slots.block.flow;


import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;


@@ -52,15 +52,15 @@ public class FlowRuleTest {


when(context.getOrigin()).thenReturn(""); when(context.getOrigin()).thenReturn("");
when(node.getClusterNode()).thenReturn(cn); when(node.getClusterNode()).thenReturn(cn);
when(cn.passQps()).thenReturn(1l);
when(cn.passQps()).thenReturn(1d);


assertTrue(flowRule.passCheck(context, node, 1, new Object[0]) == false);
assertFalse(flowRule.passCheck(context, node, 1));


flowRule.setGrade(RuleConstant.FLOW_GRADE_THREAD); flowRule.setGrade(RuleConstant.FLOW_GRADE_THREAD);
defaultController = new DefaultController(1, flowRule.getGrade()); defaultController = new DefaultController(1, flowRule.getGrade());
flowRule.setRater(defaultController); flowRule.setRater(defaultController);
when(cn.curThreadNum()).thenReturn(1); when(cn.curThreadNum()).thenReturn(1);
assertTrue(flowRule.passCheck(context, node, 1, new Object[0]) == false);
assertTrue(!flowRule.passCheck(context, node, 1));
} }


@Test @Test
@@ -79,17 +79,16 @@ public class FlowRuleTest {
DefaultNode dn = mock(DefaultNode.class); DefaultNode dn = mock(DefaultNode.class);


when(context.getName()).thenReturn("entry1"); when(context.getName()).thenReturn("entry1");
when(dn.passQps()).thenReturn(1l);
assertTrue(flowRule.passCheck(context, dn, 1, new Object[0]) == false);
when(dn.passQps()).thenReturn(1d);
assertFalse(flowRule.passCheck(context, dn, 1));


when(context.getName()).thenReturn("entry2"); when(context.getName()).thenReturn("entry2");
assertTrue(flowRule.passCheck(context, dn, 1, new Object[0]));
assertTrue(flowRule.passCheck(context, dn, 1));


// Strategy == relate // Strategy == relate
flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN); flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN);
ClusterNode cn = mock(ClusterNode.class); ClusterNode cn = mock(ClusterNode.class);
assertTrue(flowRule.passCheck(context, dn, 1, new Object[0]) == true);

assertTrue(flowRule.passCheck(context, dn, 1));
} }


@Test @Test
@@ -106,7 +105,7 @@ public class FlowRuleTest {
Context context = mock(Context.class); Context context = mock(Context.class);
DefaultNode dn = mock(DefaultNode.class); DefaultNode dn = mock(DefaultNode.class);
when(context.getOrigin()).thenReturn("origin1"); when(context.getOrigin()).thenReturn("origin1");
when(dn.passQps()).thenReturn(1l);
when(dn.passQps()).thenReturn(1d);
when(context.getOriginNode()).thenReturn(dn); when(context.getOriginNode()).thenReturn(dn);


/* /*
@@ -115,9 +114,9 @@ public class FlowRuleTest {
*/ */
ClusterNode cn = mock(ClusterNode.class); ClusterNode cn = mock(ClusterNode.class);
when(dn.getClusterNode()).thenReturn(cn); when(dn.getClusterNode()).thenReturn(cn);
when(cn.passQps()).thenReturn(1l);
when(cn.passQps()).thenReturn(1d);
assertTrue(flowRule.passCheck(context, dn, 1, new Object[0]) == false); assertTrue(flowRule.passCheck(context, dn, 1, new Object[0]) == false);
when(cn.passQps()).thenReturn(0l);
when(cn.passQps()).thenReturn(0d);
assertTrue(flowRule.passCheck(context, dn, 1, new Object[0])); assertTrue(flowRule.passCheck(context, dn, 1, new Object[0]));


flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN); flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN);


+ 1
- 1
sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/controller/DefaultControllerTest.java View File

@@ -16,7 +16,7 @@ public class DefaultControllerTest {


@Test @Test
public void testCanPassForQps() { public void testCanPassForQps() {
long threshold = 10;
double threshold = 10;
TrafficShapingController controller = new DefaultController(threshold, RuleConstant.FLOW_GRADE_QPS); TrafficShapingController controller = new DefaultController(threshold, RuleConstant.FLOW_GRADE_QPS);
Node node = mock(Node.class); Node node = mock(Node.class);
when(node.passQps()).thenReturn(threshold - 1) when(node.passQps()).thenReturn(threshold - 1)


+ 7
- 7
sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpControllerTest.java View File

@@ -38,26 +38,26 @@ public class WarmUpControllerTest extends AbstractTimeBasedTest {


Node node = mock(Node.class); Node node = mock(Node.class);


when(node.passQps()).thenReturn(8L);
when(node.previousPassQps()).thenReturn(1L);
when(node.passQps()).thenReturn(8d);
when(node.previousPassQps()).thenReturn(1d);


assertFalse(warmupController.canPass(node, 1)); assertFalse(warmupController.canPass(node, 1));


when(node.passQps()).thenReturn(1L);
when(node.previousPassQps()).thenReturn(1L);
when(node.passQps()).thenReturn(1d);
when(node.previousPassQps()).thenReturn(1d);


assertTrue(warmupController.canPass(node, 1)); assertTrue(warmupController.canPass(node, 1));


when(node.previousPassQps()).thenReturn(10L);
when(node.previousPassQps()).thenReturn(10d);


for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
sleep(100); sleep(100);
warmupController.canPass(node, 1); warmupController.canPass(node, 1);
} }
when(node.passQps()).thenReturn(8L);
when(node.passQps()).thenReturn(8d);
assertTrue(warmupController.canPass(node, 1)); assertTrue(warmupController.canPass(node, 1));


when(node.passQps()).thenReturn(10L);
when(node.passQps()).thenReturn(10d);
assertFalse(warmupController.canPass(node, 1)); assertFalse(warmupController.canPass(node, 1));
} }
} }

+ 5
- 5
sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpRateLimiterControllerTest.java View File

@@ -22,15 +22,15 @@ public class WarmUpRateLimiterControllerTest {


Node node = mock(Node.class); Node node = mock(Node.class);


when(node.passQps()).thenReturn(100L);
when(node.previousPassQps()).thenReturn(100L);
when(node.passQps()).thenReturn(100d);
when(node.previousPassQps()).thenReturn(100d);


assertTrue(controller.canPass(node, 1)); assertTrue(controller.canPass(node, 1));


long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
assertTrue(controller.canPass(node, 1)); assertTrue(controller.canPass(node, 1));
long cost = System.currentTimeMillis() - start; long cost = System.currentTimeMillis() - start;
assertTrue(cost >= 100 && cost <= 110);
assertTrue(cost >= 100 && cost <= 120);
} }


@Test @Test
@@ -39,8 +39,8 @@ public class WarmUpRateLimiterControllerTest {


Node node = mock(Node.class); Node node = mock(Node.class);


when(node.passQps()).thenReturn(100L);
when(node.previousPassQps()).thenReturn(100L);
when(node.passQps()).thenReturn(100d);
when(node.previousPassQps()).thenReturn(100d);


assertTrue(controller.canPass(node, 1)); assertTrue(controller.canPass(node, 1));




+ 12
- 12
sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/vo/NodeVo.java View File

@@ -63,12 +63,12 @@ public class NodeVo {
vo.parentId = parentId; vo.parentId = parentId;
vo.resource = node.getId().getShowName(); vo.resource = node.getId().getShowName();
vo.threadNum = node.curThreadNum(); vo.threadNum = node.curThreadNum();
vo.passQps = node.passQps();
vo.blockQps = node.blockQps();
vo.totalQps = node.totalQps();
vo.averageRt = node.avgRt();
vo.successQps = node.successQps();
vo.exceptionQps = node.exceptionQps();
vo.passQps = (long) node.passQps();
vo.blockQps = (long) node.blockQps();
vo.totalQps = (long) node.totalQps();
vo.averageRt = (long) node.avgRt();
vo.successQps = (long) node.successQps();
vo.exceptionQps = (long) node.exceptionQps();
vo.oneMinuteException = node.totalException(); vo.oneMinuteException = node.totalException();
vo.oneMinutePass = node.totalRequest() - node.blockRequest(); vo.oneMinutePass = node.totalRequest() - node.blockRequest();
vo.oneMinuteBlock = node.blockRequest(); vo.oneMinuteBlock = node.blockRequest();
@@ -102,12 +102,12 @@ public class NodeVo {
NodeVo vo = new NodeVo(); NodeVo vo = new NodeVo();
vo.resource = name; vo.resource = name;
vo.threadNum = node.curThreadNum(); vo.threadNum = node.curThreadNum();
vo.passQps = node.passQps();
vo.blockQps = node.blockQps();
vo.totalQps = node.totalQps();
vo.averageRt = node.avgRt();
vo.successQps = node.successQps();
vo.exceptionQps = node.exceptionQps();
vo.passQps = (long) node.passQps();
vo.blockQps = (long) node.blockQps();
vo.totalQps = (long) node.totalQps();
vo.averageRt = (long) node.avgRt();
vo.successQps = (long) node.successQps();
vo.exceptionQps = (long) node.exceptionQps();
vo.oneMinuteException = node.totalException(); vo.oneMinuteException = node.totalException();
vo.oneMinutePass = node.totalRequest() - node.blockRequest(); vo.oneMinutePass = node.totalRequest() - node.blockRequest();
vo.oneMinuteBlock = node.blockRequest(); vo.oneMinuteBlock = node.blockRequest();


Loading…
Cancel
Save