无法避免固定窗口存在存在的问题,依然存在1秒中之内请求超出阈值的情况,特别是这里只有两个小窗口,极端情况请求会翻倍
改造了Demo项目中的代码示例:
// 限流规则(已启动的时候调用)
private static void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<FlowRule>();
FlowRule rule1 = new FlowRule();
rule1.setResource("test");
// set limit qps to 5
rule1.setCount(5);
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule1.setLimitApp("default");
rules.add(rule1);
FlowRuleManager.loadRules(rules);
}
// 超出限流规则限制代码
@GetMapping("/foo")
public String apiFoo(@RequestParam(required = false) Long t) throws Exception {
if (t == null) {
t = System.currentTimeMillis();
}
long start = 0;
while (System.currentTimeMillis() % 500 != 0) {
start = System.currentTimeMillis();
continue;
}
System.out.println("开始时间:" + start);
Thread.sleep(300);
long taskstart = System.currentTimeMillis();
System.out.println("执行任务开始时间:" + taskstart);
for (int i = 0; i < 5; i++) {
service.test();
}
while (System.currentTimeMillis() - start < 500) {
continue;
}
System.out.println(System.currentTimeMillis());
Thread.sleep(500);
for (int i = 0; i < 5; i++) {
service.test();
}
long taskend = System.currentTimeMillis();
System.out.println("执行任务结束时间:" + taskend);
System.out.println("总执行时间:" + (taskend - start));
System.out.println("实际执行时间:" + (taskend - taskstart));
return null;
}
结果:
从结果来看,配置的规则是5,但实际上,还是存在1秒中之内资源调用了10次。是我使用的方式不对,还是说这种请求情况就是允许的
3条答案
按热度按时间polkgigr1#
必然存在,如果要求精度高 可以缩小窗口间隔 默认500ms 可以按需自己设置?
camsedfj2#
必然存在,如果要求精度高 可以缩小窗口间隔 默认500ms 可以按需自己设置?
既然这种情况无法避免,比较好奇那为啥默认是500ms,是因为这样已经适用于大部分场景了吗,毕竟可能确实绝大部分场景不需要那么精准的流控。但主要疑惑的点在于500ms间隔的窗口相比于1s的固定窗口优势在哪里
nom7f22z3#
必然存在,如果要求精度高 可以缩小窗口间隔 默认500ms 可以按需自己设置?
既然这种情况无法避免,比较好奇那为啥默认是500ms,是因为这样已经适用于大部分场景了吗,毕竟可能确实绝大部分场景不需要那么精准的流控。但主要疑惑的点在于500ms间隔的窗口相比于1s的固定窗口优势在哪里
你无论把窗口调成多么的小,都无法解决超出限流的问题,调小只是降低了出现问题的概率,窗口越小,超出限流的概率就越小