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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Servlet 3.0/3.1 中的异步处理

    在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求,即每一次Http请求都由某一个线程从头到尾负责处理.如果一个请求需要进行IO操作,比如访问数据库.调用第三方服务接口等,那么其所对应的线程将同步地等待IO操作完成, 而IO操作是非常慢的,所以此时的线程并不能及时地释放回线程池以供后续使用,在并发量越来越大的情况下,这将带来严重的性能问题.即便是像Spring.Struts这样的高层框架也脱离不了这样的桎梏,因为他们都是建立在Servlet之上的.

  • Jquery+ajax+JAVA(servlet)实现下拉菜单异步取值

    首先来看工程结构图: 项目所需要的包,如下所示: JSP代码: <%@ page language="java" import="java.util.*" pageEncoding="GBK"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServe

  • java基于servlet的文件异步上传

    在这里使用了基于servlet的文件异步上传,好了废话不多说,直接上代码了... package com.future.zfs.util; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.Iterator; import java.util.List; import javax.servlet.ServletException; import javax.s

  • Tomcat怎么实现异步Servlet

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

  • 详解Tomcat是如何实现异步Servlet的

    前言 通过我之前的Tomcat系列文章,相信看我博客的同学对Tomcat应该有一个比较清晰的了解了,在前几篇博客我们讨论了Tomcat在SpringBoot框架中是如何启动的,讨论了Tomcat的内部组件是如何设计以及请求是如何流转的,那么我们这边博客聊聊Tomcat的异步Servlet,Tomcat是如何实现异步Servlet的以及异步Servlet的使用场景. 手撸一个异步的Servlet 我们直接借助SpringBoot框架来实现一个Servlet,这里只展示Servlet代码: @Web

  • Tomcat架构设计及Servlet作用规范讲解

    目录 1.Servlet规范 1.1 Servlet作用讲解 1.2 Servlet核心API 1.3 ServletRequest 1.4 ServletResponse 2.Tomcat的设计 2.1 什么是Tomcat 2.2 Tomcat的架构结构 2.3 组件分类 1.Servlet规范 1.1 Servlet作用讲解 Servlet是JavaEE规范中的一种,主要是为了扩展Java作为Web服务的功能,统一定义了对应的接口,比如Servlet接口,HttpRequest接口,Http

  • Java Servlet异步请求开启的简单步骤

    目录 1. 背景 2. Servlet同步请求 3. Servlet异步请求 4. 异步Servlet使用方法 5. Spring中的实现例子 附:异步对象监听器 总结 1. 背景 在研究长轮询的实现过程,有使用到Servlet3的异步请求.下面就来学习一下Servlet3的异步请求 现在Servlet的版本已经到了5 2. Servlet同步请求 以Tomcat服务器为例: Http请求到达Tomcat Tomcat从线程池中取出线程处理到达Tomcat的请求 将请求Http解析为HttpSe

  • 详解从源码分析tomcat如何调用Servlet的初始化

    引言 上一篇博客我们将tomcat源码在本地成功运行了,所以在本篇博客中我们从源码层面分析,tomcat在启动的过程中,是如何初始化servlet容器的.我们平常都是将我们的服务部署到 tomcat中,然后修改一下配置文件,启动就可以对外提供 服务了,但是我们对于其中的一些流程并不是非常的了解,例如如何加载的web.xml等.这是我们分析servlet 和 sringMVC必不可少的过程. 注释源码地址:https://github.com/good-jack/tomcat_source/tre

  • 基于tomcat配置文件server.xml详解

    1. 入门示例:虚拟主机提供web服务 该示例通过设置虚拟主机来提供web服务,因为是入门示例,所以设置极其简单,只需修改$CATALINA_HOME/conf/server.xml文件为如下内容即可.其中大部分都采用了默认设置,只是在engine容器中添加了两个Host容器. <?xml version="1.0" encoding="UTF-8"?> <Server port="8005" shutdown="SH

  • 浅谈servlet3异步原理与实践

    一.什么是Servlet servlet 是基于 Java 的 Web 组件,由容器进行管理,来生成动态内容.像其他基于 Java 的组件技术一样,servlet 也是基于平台无关的 Java 类格式,被编译为平台无关的字节码,可以被基于 Java 技术的 Web 服务器动态加载并运行.容器(Container),有时候也叫做 servlet 引擎,是 Web 服务器为支持 servlet 功能扩展的部分.客户端通过 servlet 容器实现的 request/response paradigm

  • 十五道tomcat面试题,为数不多的机会!

    目录 一. Tomcat的缺省端口是多少,怎么修改? 二. Tomcat 有哪几种Connector 运行模式(优化)? 三. Tomcat有几种部署方式? 四. Tomcat容器是如何创建servlet类实例?用到了什么原理? 五. Tomcat 如何优化? 六. 内存调优 其各项参数如下: 七. 垃圾回收策略调优 八. 共享session处理 九. 添加JMS远程监控 十. 专业点的分析工具有 十一. 关于Tomcat的session数目 十二. 监视Tomcat的内存使用情况 十三. 打印

  • ServletWebServerApplicationContext创建Web容器Tomcat示例

    目录 正文 创建Web服务 一.获取Web服务器工厂 1.1 选择导入Web工厂 二.getWebServer:获取Web服务 2.1 创建TomcatEmbeddedContext 2.2. 创建TomcatWebServer 2.2.1 启动Tomcat 初始化小结 startInternal:启动Internal NamingResources启动 Service启动 启动Engine 启动TomcatEmbeddedContext 启动Executor 启动MapperListener

  • windows tomcat配置大全[详细]

    Tomcat下JSP.Servlet和JavaBean环境的配置 经常看到jsp的初学者问tomcat下如何配置jsp.servlet和bean的问题,于是总结了一下如何tomcat下配置jsp.servlet和ben,希望对那些初学者有所帮助. 第一步:下载j2sdk和tomcat:到sun官方站点(http://java.sun.com/j2se/1.4.2/download.html)下载j2sdk,注意下载版本为Windows Offline Installation的SDK,同时最好下

随机推荐