(三)Web模块:【2】Web3.0 新特性之异步处理


一、servlet3.0异步处理

在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求。 即每一次Http请求都由某一个线程从头到尾负责处理。 如果一个请求需要进行IO操作,比如访问数据库、调用第三方服务接口等,那么其所对应的线程将同步地等待IO操作完成, 而IO操作是非常慢的,所以此时的线程并不能及时地释放回线程池以供后续使用,在并发量越来越大的情况下,这将带来严重的性能问题。即便是像Spring、Struts这样的高层框架也脱离不了这样的桎梏,因为他们都是建立在Servlet之上的。为了解决这样的问题,Servlet 3.0引入了异步处理,然后在Servlet 3.1中又引入了非阻塞IO来进一步增强异步处理的性能。   在以前的servlet中,如果作为控制器的servlet调用了一个较为耗时的业务方法,则servlet必须等到业务执行完后才会生成响应,这使得这次调用成了阻塞式调用,效率比较差。   Servlet3.0支持异步处理支持,Servlet接收到请求之后,可能首先需要对请求携带的数据进行一些预处理;接着,Servlet线程将请求转交给一个异步线程来执行业务处理,线程本身返回至容器,此时Servlet还没有生成响应数据,异步线程处理完业务以后,可以直接生成响应数据(异步线程拥有ServletRequest和ServletResponse对象的引用),或者将请求继续转发给其他Servlet。

二、同步Servlet

@WebServlet(value = "/sync")
public class HelloSyncServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(Thread.currentThread()+" start..."+"==>"+System.currentTimeMillis());
        try {
            sayHello();
        } catch (Exception e) {
            e.printStackTrace();
        }
        resp.getWriter().write("hello...");
        System.out.println(Thread.currentThread()+" end..."+"==>"+System.currentTimeMillis());
    }

    public void sayHello() throws Exception {
        System.out.println(Thread.currentThread()+" processing...");
        Thread.sleep(3000);
    }
}

三、配置异步的 servlet 与 filter

  (1)通过注解asyncSupported=true实现

  (2)通过web.xml配置

    <servlet>
        <servlet-name>asyncservlet-name>
        <servlet-class>com.njf.servlet.AsyncServletservlet-class>
        <async-suppored>trueasync-suppored>       
    servlet>
    <servlet-mapping>
        <servlet-name>asyncservlet-name>
        <url-pattern>/asyncurl-pattern>
    servlet-mapping>

  对于使用传统的部署描述文件web.xml配置Servlet和过滤器的情况,Servlet3.0为标签增加了子标签,该标签的默认取值为false,要启用异步处理支持,则将其设为true即可。

  对于使用Servlet3.0提供的@WebServlet和@WebFilter进行Servlet或过滤器配置的情况,这两个标注都提供了asyncSupported属性,默认该属性的取值为false,要启动异步处理支持,只需将该属性设置为true即可。

四、

五、

相关