关闭

Tomcat怎么实现异步Servlet

标签: tomcatservlet异步web服务
6488人阅读 评论(8) 收藏 举报
分类:

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

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

 Servlet同步处理

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

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就会请求对象和响应对象进行回收处理或关闭连接。

========广告时间========

公众号的菜单已分为“分布式”、“机器学习”、“深度学习”、“NLP”、“Java深度”、“Java并发核心”、“JDK源码”、“Tomcat内核”等,可能有一款适合你的胃口。

鄙人的新书《Tomcat内核设计剖析》已经在京东销售了,有需要的朋友可以购买。感谢各位朋友。

为什么写《Tomcat内核设计剖析》

=========================

欢迎关注:

这里写图片描述

5
4
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

tomcat servlet3的异步化原理理解

之所以想起来扒这个servlet 3的异化步原理,原因是前几天写了一篇关于消息队列的pull与push模式理解.从对spring jms消息队列的客户端实现来看activemq服务端并没有真正的实现push.所以想搞清楚tomcat是如何实现servlet3的异步化。tomcat如何处理请求从客户端...
  • zhurhyme
  • zhurhyme
  • 2017-07-28 10:12
  • 424

Tomcat的异步通讯配置----使用NIO

Tomcat的异步通讯配置----使用NIO
  • jackpk
  • jackpk
  • 2014-06-12 07:50
  • 3403

Java——Ajax+Tomcat完成异步请求

Ajax最为网页异步交互技术相信大家并不陌生,这里我也不做过多介绍,详情点击(百度百科)。很多框架也封装了Ajax技术,使用起来更加简单,比如jQuery等等,这里为了了解原理,我们使用原生的Ajax。   我们以注册用户时,判断用户ID是否存在为例,实现一个最简单的异步请求,当我们鼠标离...
  • u010926964
  • u010926964
  • 2015-10-30 16:31
  • 2363

Servlet 3.0+tomcat 7.0+jdk1.7 异步

首先在各自的官网上下载 tomcat7.0: jdk1.7:
  • IamstudyingJava
  • IamstudyingJava
  • 2014-06-23 16:47
  • 4807

Tomcat的三种模式及并发调优

omcat的运行模式有3种,即BIO、NIO和APR。下面就这三种分别介绍: 1、bio 默认的模式,性能非常低下,没有经过任何优化处理和支持. 2、nio 利用java的异步io护理技术,noblocking IO技术. 想运行在该模式下,直接修改server.xml...
  • sfdst
  • sfdst
  • 2017-03-15 18:07
  • 511

Servlet 3特性:异步Servlet

Servlet3是Tomcat7出现的新特性,所以需要先安装tomcat7 理解异步Servlet之前,让我们试着理解为什么需要它。假设我们有一个Servlet需要很多的时间来处理,类似下面的内容: LongRunningServlet.java package com.journalde...
  • kuyuyingzi
  • kuyuyingzi
  • 2014-01-28 16:23
  • 16806

javaweb异步导出

  • 2014-01-20 09:42
  • 6.13MB
  • 下载

深入理解Tomcat

简介tomcat是一个web服务器,运行jsp和servlet,使用HTTP与客户端(通常是浏览器)进行通信。构成下图是tomcat的架构,可以看出:核心内容是Connector和Container组件。一个Server服务器中可能有多个Service,Service可以暂时理解为“服务”。Serv...
  • u010066934
  • u010066934
  • 2016-06-14 14:59
  • 2954

使用异步servlet提升性能

本文针对当今 webapp 中一种常碰到的问题,介绍相应的性能优化解决方案。如今的WEB程序不再只是被动地等待浏览器的请求, 他们之间也会互相进行通信。 典型的场景包括 在线聊天, 实时拍卖等 —— 后台程序大部分时间与浏览器的连接处于空闲状态,
  • renfufei
  • renfufei
  • 2016-12-08 00:03
  • 4123

异步处理Servlet接收到的请求

在Servlet组件接收到的每个请求都会产生一个线程来处理请求并返回响应,当客户端的请求处理是一项比较耗时的过程,当有大量用户请求此Servlet时,Web容器中就会产生大量的线程,导致Web容器性能急剧下降。为了解决这一问题,Servlet提供了对请求的异步处理支持。    ...
  • yanglun1
  • yanglun1
  • 2015-06-11 13:32
  • 4634
    作者
    https://github.com/sea-boat

    公众号:(内容包括分布式、机器学习、深度学习、NLP、Java深度、Java并发核心、JDK源码、Tomcat内核等等)



    微信:

    打赏作者

    如果您觉得作者写的文章有帮助到您,您可以打赏作者一瓶汽水(*^__^*)

    个人资料
    • 访问:1020517次
    • 积分:13638
    • 等级:
    • 排名:第1096名
    • 原创:321篇
    • 转载:5篇
    • 译文:1篇
    • 评论:342条
    博客专栏
    最新评论