• 异步Servlet的理解与实践


    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()
  • 相关阅读:
    traversal outlook folders
    vba get contact name in outlook
    merge all worksheets in current directory
    pandas Dataframe more filter
    Dataframe swap columns
    【数据分析&数据挖掘】数组的数据类型
    【数据分析&数据挖掘】数组的创建
    【数据分析&数据挖掘】矩阵的运算
    【数据分析&数据挖掘】矩阵的创建
    【python基础】装饰器
  • 原文地址:https://www.cnblogs.com/zolo/p/5917192.html
Copyright © 2020-2023  润新知