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)
- 或许可以将下面的部分加锁
long expectedTime = costTimeNs + latestPassedTime.get();
if (expectedTime <= currentTime) {
// Contention may exist here, but it's okay.
latestPassedTime.set(currentTime);
return true;
}
1条答案
按热度按时间dgsult0t1#
Sentinel 目前的实现为非精确实现,以兼顾高并发场景下的性能与准确性。社区可以考虑给这一块加一个“精确模式”,在确实需要完备精确的场景下 可以开启。