美文网首页
Tomcat怎么实现异步Servlet

Tomcat怎么实现异步Servlet

作者: 涉世之初99 | 来源:发表于2017-03-27 20:22 被阅读0次

来自掘金:超人汪小建

  有时Servlet在生成响应报文前必须等待某些耗时的操作,比如在等待一个可用的JDBC连接或等待一个远程Web服务的响应。对于这种情况servlet规范中定义了异步处理方式,由于Servlet中等待阻塞会导致Web容器整体的处理能力低下,所以对于比较耗时的操作可以放置到另外一个线程中进行处理,此过程保留连接的请求和响应对象,在处理完成之后可以把处理的结果通知到客户端。

  下面先看Servlet在同步情况下的处理过程,如图所示,Tomcat的客户端请求由管道处理最后会通过Wrapper容器的管道,这时它会调Servlet实例的service方法进行逻辑处理,处理完后响应客户端,整个处理由Tomcat的Executor线程池的线程处理,而线程池的最大线程数使有限制的,所以这个处理过程越短、越快把线程让回线程池就越好。但如果Servlet中的处理逻辑耗时越长就会导致长期地占用Tomcat的处理线程池,影响Tomcat的整体处理能力。

Servlet同步处理Servlet同步处理

  为了解决上面的问题引入了支持异步的Servlet,同样是客户端请求到来,然后通过管道最后进入到Wrapper容器的管道,调用Servlet实例的service后,创建一个异步上下文将耗时的逻辑操作封装起来,交给用户自己定义的线程池,这时Tomcat的处理线程就能马上回到Executor线程池,而不用等待耗时的操作完成才让出线程,从而提升了Tomcat的整体处理能力。这里要注意的是,由于后面做完耗时的操作后还需要对客户端响应,所以需要保持住Request和Response对象,以便输出响应报文到客户端。

Servlet异步处理Servlet异步处理

再结合一个简单的异步代码来看Tomcat对Servlet异步的实现:

public class AsyncServlet extends HttpServlet {

    ScheduledThreadPoolExecutor userExecutor = new ScheduledThreadPoolExecutor(5);

    public void doGet(HttpServletRequest req, HttpServletResponse res) {
        AsyncContext aCtx = req.startAsync(req, res);
        userExecutor.execute(new AsyncHandler(aCtx));
    }

}

public class AsyncHandler implements Runnable {

    private AsyncContext ctx;

    public AsyncHandler(AsyncContext ctx) {
        this.ctx = ctx;
    }

    @Override
    public void run() {
        //耗时操作
        PrintWriter pw;
        try {
            pw = ctx.getResponse().getWriter();
            pw.print("done!");
            pw.flush();
            pw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ctx.complete();
    }
}

  我们创建一个AsyncServlet,它定义了一个userExecutor线程池专门用于处理该Servlet的所有请求的耗时的逻辑操作。这样就不会占用Tomcat内部的Executor线程池,影响到对其他Servlet的处理。这种思想有点像资源隔离,耗时的操作统一由指定的线程池处理,而不要影响其它耗时少的请求处理。
Servlet的异步的实现就很好理解了,startAsync方法其实就是创建了一个异步上下文AsyncContext对象,该对象封装了请求和响应对象。然后创建一个任务用于处理耗时逻辑,后面通过AsyncContext对象获得响应对象并对客户端响应,输出“done!”。完成后要通过complete方法告诉Tomcat内部我已经处理完,Tomcat就会请求对象和响应对象进行回收处理或关闭连接。

相关文章

  • Tomcat怎么实现异步Servlet

    来自掘金:超人汪小建   有时Servlet在生成响应报文前必须等待某些耗时的操作,比如在等待一个可用的JDBC连...

  • spring boot 2

    servlet(1、同步。2、3.0异步。3、3.1非阻塞):tomcat、jetty:实现、映射、扫描注册web...

  • 解决正确配置Servlet async-supported参数报

    一、描述 环境: JDK 1.7Servlet 3.0tomcat 7   Servlet 3.0新增异步处理支持...

  • 4.1、异步servlet

    同步:接收到一个请求后,tomcat 容器提供一个线程,线程调用servlet。异步:请求异步处理后tomcat ...

  • Tomcat

    1.Tomcat概述Tomcat 是由 Apache 开发的一个 Servlet 容器,实现了对 Servlet ...

  • tomcat嵌入式启动

    Tomcat Tomcat 是由 Apache 开发的一个 Servlet 容器,实现了对 Servlet 和 J...

  • servlet 生命周期

    摘自how tomcat works 所有的 servlet 必须实现或者继承实现 javax.servlet.S...

  • Spring异步Servlet请求

    异步Servlet请求基于Servlet-api 3.0版本以上所以需要Tomcat7.0以上版本及Jetty8....

  • Servlet 并发加锁

    servlet 处理实现机制 客户端发送请求 -> servlet 容器(Tomcat) -> 调度器 -> 在容...

  • Tomcat Servlet 工作原理

    简单叙述Tomcat Servlet工作原理,做一下笔记。 Servlet Servlet有很多种实现,例如:Je...

网友评论

      本文标题:Tomcat怎么实现异步Servlet

      本文链接:https://www.haomeiwen.com/subject/mtxdottx.html