http://langyu.iteye.com/blog/707713
背景资料
对于当前的很多网络应用,并行访问的用户数会远远超过服务器上的连接数。这是由于在用户与服务器会话中,当用户在做阅读内容或是填写表格等动作时,连接可能会因为这些暂停被关闭。所以成千上万的用户可以由数百个连接来提供服务。
但是基于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中支持它。
相关推荐
赠送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 服务jar包
赠送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-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....
java运行依赖jar包
Jetty cometd(Continuation)学习笔记,自己用的,别人那down的网页
这个压缩包包含Jetty 8版本的实现及其依赖库,是学习和理解Jetty工作原理,尤其是NIO(非阻塞I/O)和Servlet容器实现的宝贵资源。 Jetty 8在设计时特别强调了性能和可扩展性,它使用了Java NIO(New I/O)API来处理...
java运行依赖jar包
java运行依赖jar包
java运行依赖jar包
java运行依赖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由Eclipse基金会维护,是Java社区中的一个重要组件,尤其在嵌入式系统和微服务领域中备受青睐。下面我们将深入探讨Jetty的核心特性、与Tomcat的对比以及如何使用。 1. **Jetty的核心特性** - **轻量级**:...
Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立...
赠送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-...
- Jetty是由Mortbay Consulting开发的,它是一个完全符合Java Servlet和JSR-315(Java EE 6 Web Profile)标准的服务器。 - 它不仅支持Servlet,还支持JSP、WebSocket、HTTP/2等技术,提供了对多种协议的支持,如...
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 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立...
注:下文中的 *** 代表文件名中的组件名称。 # 包含: 中文-英文对照文档:【***-javadoc-API文档-中文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 ...