NIO+异步-jetty实现

NIO+异步的方式能让少量的线程(资源)做大量的事情,这适用于很多应用场景,比如代理服务、api服务、长连接服务等等,这些应用如果用同步方式将耗费大量机器资源。尽管NIO+异步能提高系统吞吐量,但其并不能让一个请求的等待时间下降,相反可能会增加等待时间。

Jetty  Continuation

从jetty7,Continuations  API已经扩展成为一个通用的API,将异步工作在任何servlet-3.0容器中,以及7、8或9的延续,也将阻止任何servlet2.5容器的工作模式的延续,应该被认为是一种应用抽象上异步servlet实现了可移植层。


Jetty 的 Continuation 机制

Continuation机制是Jetty用于更好的支持异步Servlet的机制。

讨论 Jetty 的 Continuation 机制,首先需要提到 Ajax 技术,Ajax 技术是当前开发 Web 应用的非常热门的技术,也是 Web 2.0 的一个重要的组成部分。Ajax 技术中的一个核心对象是 XMLHttpRequest 对象,这个对象支持异步请求,所谓异步请求即是指当客户端发送一个请求到服务器的时候,客户端不必一直等待服务器的响应。这样就不会造成整个页面的刷新,给用户带来更好的体验。而当服务器端响应返回时,客户端利用一个 Javascript 函数对返回值进行处理,以更新页面上的部分元素的值。但很多时候这种异步事件只是在很小一部分的情况下才会发生,那么怎么保证一旦服务器端有了响应之后客户端马上就知道呢,我们有两种方法来解决这个问题,一是让浏览器每隔几秒请求服务器来获得更改,我们称之为轮询。二是服务器维持与浏览器的长时间的连接来传递数据,长连接的技术称之为 Comet技术。

大家很容易就能发现轮询方式的主要缺点是产生了大量的传输浪费。因为可能大部分向服务器的请求是无效的,也就是说客户端等待发生的事件没有发生,如果有大量的客户端的话,那么这种网络传输的浪费是非常厉害的。特别是对于服务器端很久才更新的应用程序来讲,比如邮件程序,这种浪费就更是巨大了。并且对 Server 端处理请求的能力也相应提高了要求。如果很长时间才向 Server 端发送一次请求的话,那么客户端就不能的得到及时的响应。

如果使用 Comet 技术的话,客户端和服务器端必须保持一个长连接,一般情况下,服务器端每一个 Servlet 都会独占一个线程,这样就会使得服务器端有很多线程同时存在,这在客户端非常多的情况下也会对服务器端的处理能力带来很大的挑战。

Jetty 利用 Java 语言的非堵塞 I/O 技术来处理并发的大量连接。 Jetty 有一个处理长连接的机制:一个被称为 Continuations 的特性。利用 Continuation 机制,Jetty 可以使得一个线程能够用来同时处理多个从客户端发送过来的异步请求,以达到jetty高性能的特点。具体说来,Jetty实现了一个 基于java.nio API 的SelectChannelConnector,允许它维持每个连接开放而不用消耗一个线程。当连接挂起时,Connector将请求维持在未决 Continuations队列里,用来服务请求的线程返回给TheadPool,这样,该线程又可以服务于其他请求。暂停的请求停留在未决 Continuations 队列里直到指定的过期时间,或者在它的Continuation上调用resume()方法。详情

NIO+异步-jetty实现_第1张图片

核心就是把三件不同的事情隔离开,并用不同的线程去处理,最大限度地提高了利用NIO的异步和通知特性。


总结就一句:分而治之,将任务拆分开来,由专门的人负责专门的任务。

你可能感兴趣的:(Framework)