Sentinel SpringMVC异步情况下System的Thread限流计数有问题

inb24sb2  于 2022-10-19  发布在  Spring
关注(0)|答案(2)|浏览(202)

背景

使用SpringMVC进行Sentinel限流,配置了System的Thread最大数限流规则。

当使用SpringMVC @Callable 异步模式后,SystemRule的当前线程数会不停的放大,一直递增不扣减,请求次数超过最大线程数就会出现BlockingException,后面所有请求都会是这个错,无法恢复。

业务代码:

@ResponseBody
@GetMapping("/async")
public Callable<String> async() throws Exception {
    Callable<String> callable = () -> {
        TimeUnit.MILLISECONDS.sleep(50); //
        return "hello world";
    };
    return callable;
}

问题分析

通过打断点分析发现是因为SpringMVC异步情况下preHandle会进来两次,Sentinel的AbstractSentinelInterceptor拦截器会两次计数,导致Entry没有退出。

tv6aics1

tv6aics12#

#2810 @sczyh30@brotherlu-xcq 使用栈来替换之前的引用计数
preHandler 入栈一个 preEvent
postHandler 中入栈 postEvent
afterCompletion 对事件进行闭合处理 ,一个 postEvent 和他之前连续最远的一个 preEvent 进行匹配闭合,

相关问题