Sentinel [BUG] ThrottlingController 窄时间窗口内大量并发访问时可能流控失效

ss2ws0br  于 4个月前  发布在  其他
关注(0)|答案(1)|浏览(138)

Issue Description

Type: bug report

Describe what happened

ThrottlingController 窄时间窗口内大量并发访问时可能流控失效

private boolean checkPassUsingNanoSeconds(int acquireCount, double maxCountPerStat) {
        final long maxQueueingTimeNs = maxQueueingTimeMs * MS_TO_NS_OFFSET;
        long currentTime = System.nanoTime();
        // Calculate the interval between every two requests.
        final long costTimeNs = Math.round(1.0d * MS_TO_NS_OFFSET * statDurationMs * acquireCount / maxCountPerStat);
       // Expected pass time of this request.
        long expectedTime = costTimeNs + latestPassedTime.get();

        if (expectedTime <= currentTime) {
            // Contention may exist here, but it's okay.
            latestPassedTime.set(currentTime);
            return true;
        } 
       // ...

if (expectedTime <= currentTime) 这里没有并发控制,短时间多线程可能同时进入。
比如对于配置:count=1,
在用jmeter测试时发现如果把时间窗调到1s,线程数1000(意味着请求密集发生),pass的数量经常>1,没有达到流控目的。
如果我对这个方法有任何误解,请告知我,非常感谢。

How to reproduce it (as minimally and precisely as possible)

  1. 或许可以将下面的部分加锁
long expectedTime = costTimeNs + latestPassedTime.get();

if (expectedTime <= currentTime) {
    // Contention may exist here, but it's okay.
    latestPassedTime.set(currentTime);
    return true;
}
dgsult0t

dgsult0t1#

Sentinel 目前的实现为非精确实现,以兼顾高并发场景下的性能与准确性。社区可以考虑给这一块加一个“精确模式”,在确实需要完备精确的场景下 可以开启。

相关问题