WebAsyncTask异步超时的原理

WebAsyncTask异步超时的原理

写在前面

我是从今年9月初报名,9月中旬开始学习,刚开始报名的时候也有些忐忑,主要是怕学不到东西,又或者自己到底能不能按照课程计划去进行。幸运的是,我坚持下来了,在这里遇到了各位前辈,并从老师身上学到的不少东西,譬如,他们的想法、思路,在碰到一个问题的时候该如何思考,从哪里下手等等。

首先感谢的奇点的老师,他是第一个引路人,很喜欢听他讲课,深入浅出,我那时候就在想,哇,什么时候我才能够拥有这种水平,并且可以积累这么多、这么深厚的知识啊!从他的身上,我学会了怎么一步步的查看源码,我以前是很抗拒看源码的,可能是突然开窍了,又或者是喜欢这个老师,亦或者老师上课带得好,我开始一步步地步入源码的世界,突然发现,原来世界这么精彩!因为通过源码,其实自己是可以得到很多问题的答案的,也不用每次都上一些博客、论坛去找答案,因为有时候别人的不一定对的。尽管,在不懂的情况下,查看别人写的博客确实是个好选择,帮助自己本身理解问题,但能学会查看源码也是必不可少的一份技能啊。

概述

最近接触了springMVC的异步模式,总结下来有两个优点:

  • 第一当然是节约tomcat容器的线程
  • 可以利用异步超时,起到一定的超时降级保护

注意:在Controller中使用时,一定要注意做好接口的线程池隔离,让慢的接口使用固定数量的线程池, 否则从tomcat减少的线程会转移到应用里,导致拥塞,在部分接口下游异常的情况的情况下,会出现影响正常接口的服务

在这里插入图片描述

springMVC默认使用的是一个线程池,建议根据接口指定不同的线程池

在这里插入图片描述

原理

在这里插入图片描述

异步模式处理步骤概述如下:
  1. 当Controller返回值是WebAsyncTask的时候

  2. Spring就会将Callable交给TaskExecutor去处理(一个隔离的线程池)

  3. 与此同时将DispatcherServlet里的拦截器、Filter等等都马上退出主线程,但是response仍然保持打开的状态

  4. Callable线程处理完成后,Spring MVC将请求重新派发给容器**(注意这里的重新派发,和后面讲的拦截器密切相关)**

  5. 根据Callabel返回结果,继续处理(比如参数绑定、视图解析等等就和之前一样了)~~~~

Spring MVC异步模式中使用Filter和HandlerInterceptor

看到上面的异步访问,不免我们会新生怀疑,若是普通的拦截器HandlerInterceptor,还生效吗?若生效,效果是怎么样的?

经过验证,如果我们使用的是普通的Spring MVC的拦截器,preHandler会执行两次。所以我们在书写preHandler的时候,一定要特别的注意,要让preHandler即使执行多次,也不要受到影响(幂等)

除此之外,Spring MVC给提供了异步拦截器,能让我们更深入的参与进去异步request的生命周期里面去。其中最为常用的为:AsyncHandlerInterceptor

疑问:WebAsyncTask是如何实现异步超时

WebAsyncTask有一个特性,可以设置异步处理线程的超时时间,一旦超时以后,就释放连接,中断线程,以保护系统资源,那么这究竟是如何实现的呢?这个问题的核心就是解决如何在线程池里,中断指定的异步线程(正在执行)

关键代码

在这里插入图片描述
每一个处理请求的线程会调用startCallableProcessing方法,在该方法内,向线程池提交task, 并将获得的future对象 ,设置到一个new CallableInterceporChain()对象中,用于超时中断该线程。通过对asyncWebRequest设置超时回调(传入匿名内部类对象),将CallableInterceporChaing关联到请求中来,最后在超时回调中执行future.cancel()

@Override
	public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
   

		if (returnValue == null) {
   
			mavContainer.setRequestHandled(true);
			return;
		}

		WebAsyncTask<?> webAsyncTask = (WebAsyncTask<?>) returnValue;
		if (this
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值