`
langyu
  • 浏览: 888884 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Jetty6 Continuation

阅读更多
译注:项目中用到Jetty6的Continuation机制,翻译一篇专业文章用于学习此机制
http://docs.codehaus.org/display/JETTY/Continuations

背景资料
   对于当前的很多网络应用,并行访问的用户数会远远超过服务器上的连接数。这是由于在用户与服务器会话中,当用户在做阅读内容或是填写表格等动作时,连接可能会因为这些暂停被关闭。所以成千上万的用户可以由数百个连接来提供服务。

   但是基于AJAX的应用与传统网络应用相比有不同的业务模型(Traffic profiles)。当一个用户在填写表格的时,AJAX会请求服务器获取输入数据验证和提示信息;当一个用户在读网页内容时,AJAX请求可能会去异步获取新闻或是更新网页内容。如此一个AJAX应用,它需要与服务器不间断地连接,这样前面所说的“并行访问用户数可能会远远超过服务器并发TCP/IP连接数”的情况就不会存在了。

   这样,如果有几千位用户,你就需要几千个连接;如果有数以万计的用户,你也需要数以万计的并发连接。这对Java WEB容器来说是个巨大挑战,它必须可以处理大量的并发连接。同时,对于你的应用系统,从操作系统到JVM都需要不断地被关注着。

为每个连接分配一个线程(Thread-per-Connect)
   构建一个可扩展的Servlet服务器的最主要问题之一是如果处理线程(Thread)和连接(Connection)。传统的Java IO模型为每个TCP/IP连接关联一个线程。如果你有少量非常活跃的线程,这个模型可以扩展到每秒处理大量请求。

   然而在很多WEB应用中有这样的业务模型,当用户在阅读网页或是查找链接的时候,很多HTTP长连接几乎是空闲的。在这样的模型中,“每个连接分配一个线程”的模型在大规模部署时很难让几千线程同时支持几千用户请求。

为每个请求分配一个线程(Thread-per-Request)
   采用异步IO的NIO包可以解决这个问题,它在服务器处理请求时为每个连接分配一个线程。当在两次请求之间连接空闲的时候,线程就会返回到线程池中,并且这个连接会被放入一个NIO选择组(Select set)中去侦听新的请求。“每个请求分配一个线程”的模型对服务器来说,在损失每秒最大请求数的同时可以允许更多的连接。

AJAX轮询问题
   还有一个新的问题。AJAX作为一个WEB应用模型的出现大大改变了服务器端的业务模型。由于AJAX服务器不能将事件异步地通知到AJAX客户端,所以AJAX客户端必须去服务器端轮询等待AJAX服务器端事件。为了避免频繁轮询,AJAX服务器常常持有这次轮询请求,当超时或是有新事件时才释放它。这样AJAX服务器为了当新事件到来的时候发送请求到客户端,就应当持有客户端的一个请求,而这时客户端是空闲的。这种技术思路挺好,但破坏了“每个请求分配一个线程”的模型,因为对于每个客户端在服务器端都有一个未完成的请求。这样每个服务器为每个客户端需要一个或多个线程,在成千上万个用户时就会存在问题。


Jetty6 Continuation
   上述问题的解决方法就是Jetty6中引入的新特性--Continuation。当一个Java filter或是Servlet处理一个AJAX请求,可以使用Continuation对象有效地中断(suspend)请求并释放当前的线程。当中断超时或是在Continuation对象上调用resume方法时,这个请求会被唤醒(resume)。Jett6的聊天室Demo中,有下面的这些代码用于处理AJAX对服务器事件的轮询:

private void doPoll(HttpServletRequest request, AjaxResponse response)
{
    HttpSession session = request.getSession(true);

    synchronized (mutex)
    {
        Member member = (Member)chatroom.get(session.getId());

        // Is there any chat events ready to send?
        if (!member.hasEvents())
        {
            // No - so prepare a continuation
            Continuation continuation = ContinuationSupport.getContinuation(request, mutex);
            member.setContinuation(continuation);

            // wait for an event or timeout
            continuation.suspend(timeoutMS);
        }
        member.setContinuation(null);

        // send any events
        member.sendEvents(response);
    }
}


   所以正在处理的请求被中断用于等待可以接受的聊天事件。当其它用户在聊天室中说话的时候,这种事件会由另外一个线程通过调用下面方式来发送到每个接收方。
class Member
    {
        // ...
        public void addEvent(Event event)
        {
            synchronized (mutex)
            {
                _events.add(event);
                if (getContinuation()!=null)
                    getContinuation().resume();
            }
        }
        // ...
    }



Continuation如何工作
   Java中没有中断一个线程并随后唤醒它的机制,所以Jetty在后台同Java与Servlet规范一道完成这样的功能。首先当请求处理器(Request Hander)调用continuation.suspend(timeoutMS)方法时,一个RetryRequest运行时异常被抛出。这个异常会跳过所有的请求处理代码,由Jetty捕获并对它做特殊处理。Jetty不会为这种情况产生错误响应,而是将这个请求(Request)放入一个超时队列(Timeout Queue)并将这个请求的执行线程释放回线程池中。

   当超时期到了或是另外一个线程调用continuation.resume()方法时,那个请求就被取回。这时如果再调用continuation.suspend(timeoutMS)方法,这个方法要么返回null要么返回RetryRequest事件,请求处理器会按正常的流程产生对客户端的响应。

   这个机制使用HTTP请求处理中的无状态性来模拟一个中断(suspend)和唤醒(resume)动作。那种运行时异常(RetryRequest异常)可以让线程合理地退出请求处理器(Request Handler),任何上游的filter或是servlet都可以添加一些相关的安全上下文(Security Context)。请求在取回时,会重新进入filter/servlet链和一些安全上下文并在continuation的点上重新执行正常处理。

   另外,Continuation的API是简明的。如果它运行在一个非Jetty服务器上,它可以在getEvent时使用简单的wait/notify去中断请求。如果Continuation是按我想的这样在工作,我计划在Servlet3.0中支持它。
  • 大小: 52 KB
2
0
分享到:
评论

相关推荐

    jetty-continuation-8.1.8.v20121106-API文档-中文版.zip

    赠送jar包:jetty-continuation-8.1.8.v20121106.jar; 赠送原API文档:jetty-continuation-8.1.8.v20121106-javadoc.jar; 赠送源代码:jetty-continuation-8.1.8.v20121106-sources.jar; 赠送Maven依赖信息文件:...

    jetty-continuation-7.4.2.v20110526.jar

    jetty-continuation-7.4.2.v20110526.jar jetty 服务jar包

    jetty-continuation-8.1.8.v20121106-API文档-中英对照版.zip

    赠送jar包:jetty-continuation-8.1.8.v20121106.jar; 赠送原API文档:jetty-continuation-8.1.8.v20121106-javadoc.jar; 赠送源代码:jetty-continuation-8.1.8.v20121106-sources.jar; 赠送Maven依赖信息文件:...

    jetty相关的全部jar包

    jetty-security-9.4.8.v20171121.jar,jetty-io-9.4.8.v20171121.jar,jetty-continuation-9.4.8.v20171121.jar,jetty-client-9.4.8.v20171121.jar,jetty-jmx-9.4.8.v20171121.jar,jetty-plus-9.4.8.v20171121....

    jetty-continuation-9.2.9.v20150224.jar

    java运行依赖jar包

    Jetty cometd(Continuation)学习笔记

    Jetty cometd(Continuation)学习笔记,自己用的,别人那down的网页

    jetty 8及依赖包

    这个压缩包包含Jetty 8版本的实现及其依赖库,是学习和理解Jetty工作原理,尤其是NIO(非阻塞I/O)和Servlet容器实现的宝贵资源。 Jetty 8在设计时特别强调了性能和可扩展性,它使用了Java NIO(New I/O)API来处理...

    jetty-continuation-9.2.15.v20160210.jar

    java运行依赖jar包

    jetty-continuation-9.2.17.v20160517.jar

    java运行依赖jar包

    jetty-continuation-7.6.10.v20130312.jar

    java运行依赖jar包

    jetty-continuation-8.1.15.v20140411.jar

    java运行依赖jar包

    jmeter测试相关jar包

    org.eclipse.jetty.continuation_9.1.1.v20140108.jar org.eclipse.jetty.continuation.source_9.1.1.v20140108.jar org.eclipse.jetty.deploy_9.1.1.v20140108.jar org.eclipse.jetty.deploy.source_9.1.1.v...

    jetty-distribution-9.4.12.v20180830

    Jetty由Eclipse基金会维护,是Java社区中的一个重要组件,尤其在嵌入式系统和微服务领域中备受青睐。下面我们将深入探讨Jetty的核心特性、与Tomcat的对比以及如何使用。 1. **Jetty的核心特性** - **轻量级**:...

    jetty-io-8.1.8.v20121106.jar

    Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立...

    jetty-client-9.4.43.v20210629-API文档-中文版.zip

    赠送jar包:jetty-client-9.4.43.v20210629.jar; 赠送原API文档:jetty-client-9.4.43.v20210629-javadoc.jar; 赠送源代码:jetty-client-9.4.43.v20210629-sources.jar; 赠送Maven依赖信息文件:jetty-client-...

    jetty7.4.2

    - Jetty是由Mortbay Consulting开发的,它是一个完全符合Java Servlet和JSR-315(Java EE 6 Web Profile)标准的服务器。 - 它不仅支持Servlet,还支持JSP、WebSocket、HTTP/2等技术,提供了对多种协议的支持,如...

    Jetty多版本软件包

    Jetty软件包内容: jetty-distribution-9.4.51.v20230217.tar.gz jetty-distribution-9.4.51.v20230217.zip jetty-home-10.0.15.tar.gz jetty-home-10.0.15.zip jetty-home-11.0.15.tar.gz jetty-home-11.0.15.zip ...

    jetty-io-9.4.43.v20210629.jar

    Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立...

    jetty-continuation-8.1.8.v20121106.jar中文-英文对照文档.zip

    注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 ...

Global site tag (gtag.js) - Google Analytics