Tomcat怎么实现异步Servlet

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

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

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

再结合一个简单的异步代码来看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就会请求对象和响应对象进行回收处理或关闭连接。

时间: 2024-11-04 01:05:17

Tomcat怎么实现异步Servlet的相关文章

使用异步servlet提升性能

本文发布之后, 收到了很多的反馈.基于这些反馈,我们更新了文中的示例,使读者更容易理解和掌握, 如果您发现错误和遗漏,希望能给我们提交反馈,帮助我们改进. 本文针对当今 webapp 中一种常碰到的问题,介绍相应的性能优化解决方案.如今的WEB程序不再只是被动地等待浏览器的请求, 他们之间也会互相进行通信. 典型的场景包括 在线聊天, 实时拍卖等 -- 后台程序大部分时间与浏览器的连接处于空闲状态, 并等待某个事件被触发. 这些应用引发了一类新的问题,特别是在负载较高的情况下.引发的状况包括线程

Other - 02 - Servlet学习笔记 - 异步Servlet

异步Servlet Servlet默认情况下都是同步的,但是Servlet可以进行异步的调用. /** * Servlet implementation class MainServlet */ @WebServlet(value = "/MainServlet", asyncSupported = true) public class AsynServlet extends HttpServlet { private static final long serialVersionUI

关于servlet3.0中的异步servlet

刚看了一下维基百科上的介绍,servlet3.0是2009年随着JavaEE6.0发布的: 到现在已经有六七年的时间了,在我第一次接触java的时候(2011年),servlet3.0就已经出现很久了,但是到现在,里边的一些东西还是没有能够好好地了解一下 最近在研究java的长连接,在了解jetty中的continuations机制的时候也重新了解了一下servlet3.0中的异步servlet机制,通过看几个博客,加上自己的一些测试,算是搞明白了一些,在这里记录一下: 在服务器的并发请求数量比

Servlet 3特性:异步Servlet

本文由 ImportNew - 彭秦进 翻译自 journaldev.欢迎加入翻译小组.转载请见文末要求. 理解异步Servlet之前,让我们试着理解为什么需要它.假设我们有一个Servlet需要很多的时间来处理,类似下面的内容: LongRunningServlet.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

在Eclipse中配置Tomcat 创建和运行Servlet/JSP

在Eclipse中配置Tomcat 创建和运行Servlet/JSP 步骤一:在Eclipse中配置Tomcat(注意下载Eclipse IDE for Java EE Developers) (1)在Eclipse中配置Tomcat.选择Window→Preferences命令,在打开的对话框左边列表框中选择Server节点中的Runtime Environments.单击窗口右侧的Add按钮,打开New Server Runtime Environmen对话框,在该对话框中可选择服务器的类型

JBoss和Tomcat版本、及Servlet、JSP规范版本对应一览 【转】

原文地址:http://blog.csdn.net/hills/article/details/40896357 JBoss和Tomcat版本.及Servlet.JSP规范版本对应一览 JBossAS version Ships with Tomcat Servlet Spec JSP Spec 3.2.3 4.1.29 2.3 1.2 3.2.4 5.0.26 2.4 2.0 3.2.5 5.0.26 2.4 2.0 3.2.6 5.0.28 2.4 2.0 3.2.7 5.0.30 2.4

Tomcat启动失败提示Servlet部署路径重复

用Java开发的项目,因为很简单,所以用的依然是Servlet.之前一切正常,但是新增了一个Servlet之后,部署到服务器,却总是启动失败,控制台打印的东西很多,但是分析发现主要错误应该是这个地方: Caused by: java.lang.IllegalArgumentException: The servlets named [RevelationServlet] and [cn.lzgd.servlet.RevelationServlet] are both mapped to the

Java+MyEclipse+Tomcat (六)详解Servlet和DAO数据库增删改查操作

此篇文章主要讲述DAO.Java Bean和Servlet实现操作数据库,把链接数据库.数据库操作.前端界面显示分模块化实现.其中包括数据的CRUD增删改查操作,并通过一个常用的JSP网站前端模板界面进行描述.参考前文: Java+MyEclipse+Tomcat (一)配置过程及jsp网站开发入门 Java+MyEclipse+Tomcat (二)配置Servlet及简单实现表单提交 Java+MyEclipse+Tomcat (三)配置MySQL及查询数据显示在JSP网页中 Java+MyE

在MAC上搭建tomcat,再使用servlet时遇到的问题。

说起来真是惭愧.在mac上配置tomcat环境时.tomcat6能正确运行.但是7,8都运行不了.具体表现是tomcat6访问127.0.0.1:8080可以显示那个界面,然而tomcat7和8都显示空白页,也就是什么都没有. 然后我去百度,找了很久没有办法.我接着想,会不会在eclipse上没问题呢?于是我在eclipse上弄了个小小的servlet,结果报错了.错误难以理解.我从各个方向去猜去查,最后在stackoverflow上看到了最标准的解答. 原来是java1.8上的jar包里面自动