servlet的异步处理机制
Java servlet是大家公认的服务器端web技术的标准,包括jsp,jsf,和大量的web框架,soap,RESTful web service api ,还有新闻供应。servlet运行在这些技术下面,以保证这些技术可以运行在任何java web服务器上。所以servlet的任何变化都会对所有与服务器有关的技术产生影响。
已经在2009年1月通过公众审核的servlet3.0,是一个包含很多重要特性的最新版本,它的出现将会给java web开发者带来更好的体验。下面就是servlet3.0所包含的新的特性。
1,支持异步处理。
2,配置简单。
3,可插入性。
4,增强既存api。
支持异步处理是servlet3.0的最重要的特征,它将更便捷服务器端ajax application的开发,以下将重点讲述servlet在支持异步处理上所做的处理,主要是连接和线程消耗。以及当今应用异步处理的实现,例如:comet和reverse ajax。最后还将介绍有关servlet3.0的其他特性。
异步支持:背景概念
web2.0迅速地改变了服务器与客户端的通信方式,servlet3.0的支持异步处理正是基于这种变化的回应。为了彻底地理解异步处理,首先我们先回顾一下http通信的进化史。
http1.0和http1.1
http1.1标准的一个重要的改善部分是能够建立持续的链接,在http1.0时代,服务器与客户端的通信在一次请求和回应后就会被关闭,但是在http1.1标准下,在多次请求的过程中,链接能够持续保持和可用。持续的连接减少了网络连接缓慢的可见状态,因为客户端不必在每次请求后都重新建立tcp连接。
基于连接的线程
解决怎样使服务器能更具有扩展性是现在许多研究人员正在进行的课题,基于http1.1持续连接的http连接线程,是研究人员们所采用的一个通用的解决方案,在这个策略下,每一个客户端与服务器端的连接都与一个服务器端的线程有联系,线程由一个服务器控制的线程池来管理,一旦一个连接关闭,负责这个连接的线程将会被收回,并重新放回线程池以备其他连接使用。依靠硬件配置,这种方式可以处理大量的并行连接,有试验表明,服务器端的内存消耗会随着连接数量的增加成比例的增长,原因很简单,线程与内存使用是成比例的。所以配置了固定数量线程的服务器会产生线程死锁现象,因此一旦服务器线程池里的线程全部被占用,来自客户端的请求就会被拒绝。另外,有很多的站点,用户请求服务器页面的机会很少,服务器连接线程在很长时间都处于闲置状态,这也是一种资源的浪费。
基于请求的线程
由于在java4的nio中新的i/o api中出现的无阻塞(non-blocking i/o)i/o处理能力,把原来的一个连接需要附加一个线程的处理方式变成只有当该请求被处理的时候才被分派线程的处理方式。当连接在请求的过程中处于闲置状态时,它会被放置到一个中央选择处理集合里,来观测新的请求而不是消耗一个独立的线程。这种模式被称为基于请求的进程。潜在的允许服务器在固定线程的基础上处理不断增长的用户连接。在相同硬件条件下,这种方式比基于连接进程方式扩展的更好。 现在很多web服务器,如:tomcat,jetty,glassfish,weglogic,websphere都通过java NIO应用这种方式。对于应用程序开发人员,这些都是以隐藏的方式进行的,不会通过servlet api暴露出来。
迎接ajax挑战
为了提供更丰富的用户体验和交互,越来越多的web application应用了ajax,应用ajax应用的用户会获得更多的与服务器的交互,不同于以往请求的是,ajax用户请求可以更频繁的被发送到服务器端,另外,客户端和脚本也在促使着服务器技术的更新,越来越多的同步请求 导致大量的线程被消耗,这使得基于请求线程方式的优点几乎销蚀殆尽。
运行缓慢,有限的资源
有些运行缓慢的后台常规工作更加恶化这个形势,例如:有些请求可能因为已经废弃的jdbc连接池或者低通量服务器端的原因而被阻塞,等待请求的线程可能被阻止很长时间直到资源再次可用。最好的办法是把请求放到一个中央集权的队列中等待可用资源,并回收不可用的线程。这种方式有效地协调了大量请求和运行缓慢的后台程序。它同时也暗示了在某种程度上放在队列里的请求是没有任何线程与之对应的。servlet3.0的支持异步通信正是为了在一个广泛的可移植的方式上(不管是否应用ajax)实现这个目标。下面的代码将阐述它是怎样实现的:
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
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
@WebServlet(name="myServlet", urlPatterns={"/slowprocess"}, asyncSupported=true)
public class MyServlet extends HttpServlet {
   
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        AsyncContext aCtx = request.startAsync(request, response);
        ServletContext appScope = request.getServletContext();
        ((Queue<AsyncContext>)appScope.getAttribute("slowWebServiceJobQueue")).add(aCtx);
    }
}
@WebServletContextListener
public class SlowWebService implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {
        Queue<AsyncContext> jobQueue = new ConcurrentLinkedQueue<AsyncContext>();
        sce.getServletContext().setAttribute("slowWebServiceJobQueue", jobQueue);
        // pool size matching Web services capacity
        Executor executor = Executors.newFixedThreadPool(10);
        while(true)
        {
            if(!jobQueue.isEmpty())
            {
                final AsyncContext aCtx = jobQueue.poll();
                executor.execute(new Runnable(){
                    public void run() {
                        ServletRequest request = aCtx.getRequest();
                        // get parameteres
                        // invoke a Web service endpoint
                        // set results
                        aCtx.forward("/result.jsp");
                    }                   
                });            
            }
        }
    }
    
    public void contextDestroyed(ServletContextEvent sce) {
    }
}

在这段代码,当asyncSupported 属性被设置为true时,response对象还没有被赋给exit方法。调用startAsync方法返回一个AsyncContext对象,它用来缓存request和response对象,该AsyncContext对象被存放在一个application域队列里,紧接着,doGet方法执行并返回,原始的request线程被回收,在ServletContextListener对象,在application开始监视上述队列并随时回收request处理过程,在request对象被处理后,你有选择调用ServletResponse.getWriter.print()方法然后调用complete方法来提交Response,或者是调用forward方法来导向一个jsp来显示结果,注意这些jsp页面是带有被设置为false的asyncSupported属性的servlets。
另外,在servlet3.0中的AsyncEvent和AsyncListener类可以给开发者对于异步生命周期事件精心的控制,你可以通过ServletRequest.addAsyncListener方法来注册一个AsyncListener类,在startAsync方法被调用后,当异步处理结束或者过期后,一个AsyncEvent被立即发送给上述已注册的AsyncListener类。AsyncEvent也像AsyncContext对象一样包含一个request和response对象。
服务器端推技术
servlet3.0异步特征的一个更重要,更有趣的应用案例就是服务器端推技术。Gtalk(一种可以使Gmail用户在线聊天的小工具)就是使用服务器端推技术的案例,Gtalk不经常访问服务器去核对是否有可以显示的新信息。相反,它等待服务器向回弹推新信息,这种方式有两种显著的优点:不用频繁发送request的低滞后通信,不浪费服务器资源和网络带宽。
ajax技术允许用户可以在处理很多请求的同时通过页面与服务器进行交互,一个普遍的用途就是用ajax来访问服务器来获得更新的状态而不打断用户操作,但是高频率访问会浪费服务器资源和网络带宽,如果服务器可以动态向浏览器弹推数据,换句话说,通过事件向客户端传送异步信息(状态改变)。ajax application将会表现的更优雅并且节省珍贵的服务器资源和网络带宽。
http协议是一个请求回复的协议,一个客户端发送请求信息到服务器端,服务器通过一个回复信息回复客户端。服务器不能初始化客户端或者发送一个非期望的信息给客户端。http协议的这个方面使得服务器弹推信息看起来不可能,但是很多有创意的技术可以绕开这个限制。
service streaming技术,允许一个服务器通过事件触发而不是从客户端发送过来的请求来向客户端发送消息,实际的实现方法是:客户端通过一个请求来初始化一个连接,回复信息会在服务器端事件发生的时候被一点一点地返回,理论上,回复信息永久持续,这些信息片可以被客户端浏览器接收,解析并显示在浏览器上。
long polling技术,也叫异步访问,是一种纯server push and client pull技术,这种技术基于Bayeux协议,像service streaming 一样,客户端通过请求与服务器建立一个连接,服务器保持该请求直到一个事件的发生,一旦事件发生,一个完整的回复信息被返回给客户端。一接收到回复信息,客户端立即发送一个新的信息,这样服务器端几乎一直持有一个通过服务器端事件触发回复消息的请求。long polling技术比service streaming 更容易在浏览器上实现。
passive piggyback技术,当服务器有更新信息需要发送给客户端时,它等待来自客户端的下一个请求,一旦接收到下一个请求,它会把该更新信息连同客户端期望的回复信息一并发送给客户端。
service streaming和long polling 技术通过ajax实现,以Comet 或者reverse ajax最为著名。
ajax改善了单用户响应性,像comet一样的服务器端推技术使得应用程序响应更具有协作性,多用户形式,而且不占用正常访问的消耗。
客户端方的技术,如:隐藏的iframe,xmlhttprequest,dojo,jquery类库不在本文讨论范围内,我们要探讨的是servlet3.0怎样帮助实现服务器端推技术。
有效线程利用:一个更广泛的解决方案。
comet一直占用一个等待在服务器端的管道返回状态更新信息,这个管道不可以再被客户端用来发送原始请求,所以comet实际上是在一个客户身上建立了两个连接,如果应用程序保持在基于请求的线程方式,每个连接都会被关联一个特殊线程,这就导致了线程数大于实际用户数。应用基于请求线程的comet应用只能在有限的线程消:耗范围内扩展。
文章摘自:https://www.cnblogs.com/liuwenting/p/8650024.html
更多java学习资料可关注:itheimaGZ获取

servlet的异步处理机制相关推荐

  1. 厉害了,Servlet3的异步处理机制

    转载自 厉害了,Servlet3的异步处理机制 Servlet3发布好几年了,又有多少人知道它的新特性呢?下面简单介绍下. 主要增加了以下特性: 1.异步处理支持 2.可插性支持 3.注解支持,零配置 ...

  2. 关于Servlet和异步Servlet

    Servlet API是Java EE标准的一部分,自1998年正式发布2.1规范以来,一直是基于Java的企业体系结构的重要组成部分. 它是一种自以为是的API,用于服务围绕一些基本概念构建的请求/ ...

  3. java filter 回调_Java 异步回调机制实例分析

    Java 异步回调机制 一.什么是回调 回调,回调.要先有调用,才有调用者和被调用者之间的回调.所以在百度百科中是这样的: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用 ...

  4. servlet的异步和非阻塞原理

    之前研究了下servlet的异步和非阻塞原理,看到一篇文章,下面有两个问题,顺便解答了下 servlet3异步原理与实践 Danniel 3楼 2019.05.18 21:31 请问,AsyncLon ...

  5. Android Handler 异步消息处理机制的妙用 创建强大的图片载入类

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 近期创建了一个群.方便大家交流,群号: ...

  6. EJB与JAVA BEAN_J2EE的异步消息机制

    EJB与JAVA BEAN_J2EE的异步消息机制 EJB与JAVA BEAN的区别 Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个 ...

  7. Android异步消息机制

    2019独角兽企业重金招聘Python工程师标准>>> 目录介绍 1.Handler的常见的使用方式 2.如何在子线程中定义Handler 3.主线程如何自动调用Looper.pre ...

  8. Android异步消息处理机制 全解析

    Android异步消息处理机制主要是指Handler的运行机制以及Hanlder所附带的MessageQueue和Looper的工作过程. 本文将通过分析源码(api-28)的形式,全面解析Handl ...

  9. Android多线程----异步消息处理机制之Handler

    虽然是国庆佳节,但也不能停止学习的脚步,我选择在教研室为祖国母亲默默地庆生. 关于Android的多线程知识,请参考本人之前的一篇博客:Android 多线程----AsyncTask异步任务详解 在 ...

最新文章

  1. 上当记,收国外快递时,注意相关责任定义
  2. ThinkPHP的标签制作
  3. jquery学习手记(6)CSS, Styling, Dimensions
  4. 30+个必知的《人工智能》会议清单
  5. 50道练习带你玩转Pandas
  6. 用tomcat 发布mule 服务 (转)
  7. LaTeX的编译速度优化方案
  8. 250W电源带i7+GTX1080?
  9. 使用Python可以做些什么
  10. 联想计算机启机按F1,电脑开机提示按f1不能正常启动怎么办
  11. 光大祖业 奉子成婚——SAS与SATA-Ⅱ专题
  12. CMD批处理实现dot命令自动运行更新
  13. 组装计算机主机算固定资产吗,​购买电脑配件组装电脑属于固定资产吗
  14. 提高项目10-编制三角函数表
  15. 从零开始学数据分析之——《线性代数》第四章 线性方程组
  16. ProxyPool 代理
  17. The server time zone value 'xxx' is unrecognized or represents more than one time zone 问题的解决方法
  18. linux 内核调试 booting the kernel.,Linux无法启动解决 booting the kernel.
  19. 微软宣布Azure DNS全面通用
  20. python判断素数_小白学Python | 你还在说你入不了门吗

热门文章

  1. 传说对决先行服显示服务器未响应,传说对决先行服
  2. 虚拟机无法显示ens33网卡设备
  3. 2021年,薪酬最高的5种编程语言,你想学哪个?
  4. 笔记本电脑玩魔兽争霸 屏幕比例小了怎么办?
  5. IFC格式BIM文件处理方案概述
  6. 线偏振光通过半波片之后的解释
  7. 腾讯企业邮箱无法登陆
  8. QQ登录100044错误解决
  9. SolidWorks装配体中让弹簧随装配体运动的方法
  10. Apache thrift初探之旅