AsyncContext理解

Servlet 3.0(JSR315)定义了Servlet/Filter的异步特性规范.

怎么理解"异步Servlet/Filter"及其使用情景?

Servlet3.0以前

流程:

  1. 容器初始化ServletRequest与ServletResponse对象.

  2. 容器调用Servlet实例的service(ServletRequest, ServletResponse)执行业务逻辑.

  3. 容器Commit ServletResponse, 将响应结果写回客户端并关闭连接.

    • Servlet接口定义
    public interface Servlet {
    public void init(ServletConfig config) throws ServletException;
    public void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException;
    public void destroy(); public ServletConfig getServletConfig();
    public String getServletInfo();
    }
    • Filter接口定义
    public interface Filter{
    public void init(FilterConfig filterConfig) throws ServletException; }

局限

  1. 执行完流程(2)后立即Commit ServletResponse, 将响应结果回写给客户端.
  2. 局限(1)导致请求的所有业务逻辑都必须在service()方法内同步执行.
  3. 局限(2)导致容器的控制线程耗用严重, 特别是长连接或者阻塞等待(DB,IO,Net)的情景.

看到这里, 是不是有点明白了!

Servlet 3.0前, Service容器调用Servlet.service()方法后就会Commit与销毁ServletResponse, 这导致所有业务逻辑都必须在service()内处理, 不管理是耗时还是不耗时的, 控制线程必须等待处理完成才能"抽身"服务新的请求.

Servlet 3.0 规范提供AsyncContext设施实现ServletResponse的delay commit.

AsyncContext原理

通过ServletRequest.startAsync()通知Servlet容器delay ServletResponse的committal, 并返回AsyncContext对象供其他线程在service()方法结束后使用.

AsyncContext套路

  1. 设置asyncSupported=true.

    • 在<servlet>或<filter>内使用<async-supported>标签
    • 在@WebServlet或@WebFilter内使用asyncSupported属性
  2. 调用ServletRequest.startAsyc()通知容器delay ServletResponse的committal, 并返回AsyncContext对象.

  3. 调用AsycContext.setTimeout()设置超时; 调用AsyncContext.addListener()添加监听器,设置start/timeout/error/complete的回调方法.

  4. 将AsyncContext对象交给工作线程处理.

    • 自定义线程池: ThreadPoolExecutor
    • 容器线程池: AsyncContext.start()
  5. 控制线程继续服务其他请求.

  6. 工作线程完成处理, 响应结果回写客户端.

    • 正常完成: 手工调用AsyncContext.complete()
    • 处理超时或发生错误, 自动调用AsyncContext.complete().

      只有AsyncContext.complete(), ServletResponse才会提交, 响应结果才会回写客户端.
    • 分发其他: 调用dispatch分发其他Servlet处理.

最佳实践: 慎重AsyncContext.setTimeout(0)

AsyncContext相关的API:

ServletRequest:

  • ServletRequest.isAsyncSupported()
  • ServletRequest.isAsyncStarted()
  • ServletRequest.startAsync(...) #多个
  • ServletRequest.getAsyncContext()

AsyncContext:

可分成下述几类

  • AsyncContext.getRequest()/getResponse()/hasOriginalRequestAndResponse()
  • AsyncContext.setTimeout()/getTimeout()
  • AsyncContext.addListener(...)/createListener()
  • AsyncContext.complete()/dispatch(...)
  • AsyncContext.start()

异步Servlet的理解与实践的更多相关文章

  1. Java网络编程中异步编程的理解

    目录 前言 一.异步,同步,阻塞和非阻塞的理解 二.异步编程从用户层面和框架层面不同角度的理解 用户角度的理解 框架角度的理解 三.为什么使用异步 四.理解这些能在实际中的应用 六.困惑 参考文章 前 ...

  2. Atitit.异步编程技术原理与实践attilax总结

    Atitit.异步编程技术原理与实践attilax总结 1. 俩种实现模式 类库方式,以及语言方式,java futuretask ,c# await1 2. 事件(中断)机制1 3. Await 模 ...

  3. Servlet 3特性:异步Servlet

    解异步Servlet之前,让我们试着理解为什么需要它.假设我们有一个Servlet需要很多的时间来处理,类似下面的内容: LongRunningServlet.java package com.jou ...

  4. 异步servlet的原理探究

    异步servlet是servlet3.0开始支持的,对于单次访问来讲,同步的servlet相比异步的servlet在响应时长上并不会带来变化(这也是常见的误区之一),但对于高并发的服务而言异步serv ...

  5. 使用tomcat7创建异步servlet

    该篇文章翻译自:http://developerlife.com/tutorials/?p=1437 一.简介 Servlet API 3.0 之前,需要使用类似Comet的方式来实现创建异步的Ser ...

  6. tornado异步请求的理解(转)

    tornado异步请求的理解 http://www.kankanews.com/ICkengine/archives/88953.shtml 官网第一段话: Tornado is a Python w ...

  7. Filter 快速开始 异步Servlet 异步请求 AsyncContext 异步线程 异步派发 过滤器拦截

    [web.xml] <filter> <filter-name>normalFilter</filter-name> <filter-class>net ...

  8. 异步Servlet和异步过虑器

    异步处理功能可以节约容器线程.此功能的作用是释放正在等待完成的线程,是该线程能够被另一请求所使用. 要编写支持异步处理的 Servlet 或者过虑器,需要设置 asyncSupported 属性为 t ...

  9. 关于servlet3.0中的异步servlet

    刚看了一下维基百科上的介绍,servlet3.0是2009年随着JavaEE6.0发布的: 到现在已经有六七年的时间了,在我第一次接触java的时候(2011年),servlet3.0就已经出现很久了 ...

随机推荐

  1. Android onKeyDown监听返回键无效

    当我们的Activity继承了TabActivity,在该类中重写onKeyDown是监听不到返回键的, 具体解决方法如下: 重写dispatchKeyEvent /** * 退出 */ @Overr ...

  2. [HTML5] Focus management using CSS, HTML, and JavaScript

    Something important to consider when coding a web application is managing the user's focus. For keyb ...

  3. [Angular] Difference between ngAfterViewInit and ngAfterContentInit

    Content is what is passed as children. View is the template of the current component. The view is in ...

  4. (ubuntu 下)tensorflow 的安装及版本升级

    对于 CPU 版本 pip3 install –upgrade tensorflow 对于 GPU 版本: pip3 install –upgrade tensorflow-gpu [TensorFl ...

  5. CocoaPods停在Analyzing dependencies的解决方案

    解决办法: 1: 换镜像索引库 国内有人建立了cocoapods的索引库镜像,可以通过如下命令更改镜像: pod repo remove master  pod repo add master htt ...

  6. 关于用什么作为dll版本号的思考

    作者:朱金灿 来源:http://blog.csdn.net/clever101 一个软件模块的版本如何维护呢?毫无疑问,它需要一个版本号.通过比对版本号就知道哪个高版本,哪个是低版本了.软件模块以d ...

  7. C#生成二维码,把二维码图片放入Excel中

    /// <summary> /// 把图片保存到excel中 /// </summary> /// <param name="excelFilePath&quo ...

  8. 【16.23%】【codeforces 586C】Gennady the Dentist

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  9. dropzone上传文件

    先上张效果图吧 1.引入dropzone的js和css文件 2.html这里我用了一个form,当然你也可以直接用一个div,无论你用什么都要加上class="dropzone" ...

  10. hadoop编程技巧(8)---Unit Testing (单元测试)

    所需的环境: Hadoop相关jar包裹(下载版本的官方网站上可以): 下载junit包裹(新以及). 下载mockito包裹: 下载mrunit包裹: 下载powermock-mockito包裹: ...