关于线程限流问题的讨论
- Dominant language
- Java
- Stars
- 23.1k
- Forks
- 8.1k
- PR merge metrics
- No merged PRs in 30d
Description
## Issue Description
bug report
### Describe what happened (or what feature you want)
sentinel采用类似于责任链的设计模式,将统计、限流、降级、监控等功能串起来,使每个环节自责更清晰(见DefaultSlotsChainBuilder),这种设计模式对于大多数关于“数量”的统计场景是没问题的,比如QPS、错误量等。但对于线程数限流(即并发限流)这样做是有问题的,详见:https://blog.csdn.net/manzhizhen/article/details/81413014。
在Sentinel中,当前服务对线程数加(请求进来)和减(请求执行完毕)的操作是在**StatisticSlot**中完成的:
@Override
public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, Object... args) throws Throwable {
// 注意: 其他代码省略
fireEntry(context, resourceWrapper, node, count, args);
**node.increaseThreadNum();**
}
@Override
public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
DefaultNode node = (DefaultNode)context.getCurNode();
// 注意: 其他代码省略
**node.decreaseThreadNum();**
}
而线程数的限流操作是在另一个类来做的,例如**SystemSlot**:
@Override
public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, Object... args) throws Throwable {
**SystemRuleManager.checkSystem(resourceWrapper);**
fireEntry(context, resourceWrapper, node, count, args);
}
其中SystemRuleManager.checkSystem的操作如下:
public static void checkSystem(ResourceWrapper resourceWrapper) throws BlockException {
// 注意: 其他代码省略
// total thread
int currentThread = Constants.ENTRY_NODE == null ? 0 : Constants.ENTRY_NODE.curThreadNum();
**if (currentThread > maxThread) {
throw new SystemBlockException(resourceWrapper.getName(), "thread");
}**
}
将统计和限流分开的这种方式,无法真正做到线程数量(也就是并发度)的精准控制,会有竞态条件产生,比较好的做法是用信号量来实现。
### Describe what you expected to happen
### How to reproduce it (as minimally and precisely as possible)
1.
2.
3.
### Tell us your environment
### Anything else we need to know?
Contributor guide
Assessment
This issue has not been assessed yet.