はじめに: Jetty は、Java で実装されたオープンソースの標準ベースの機能豊富な HTTP サーバーおよび Web サーバーです。 コンテナは商用利用は無料です。 Jetty プロジェクトは 1995 年に設立されました。Apache Geromino など、Jetty をベースにした多くの成功した製品がすでに存在しています。 JBoss、IBM Tivoli、Cisco SESMなどJetty は、従来の Web サーバーまたは動的コンテンツ サーバーとして使用できます。 Jetty は Java アプリケーションに簡単に組み込むことができます。
機能の紹介
使いやすさは、主に次の側面に反映されます:
1. XML または API を使用して Jetty を設定します。ほとんどのニーズを満たすことができます
3. Jetty を使用します。 アプリケーションへの組み込みには、Ajax を使用したスケーラビリティ
Web 2.0 が必要です。
各接続を長期間維持する必要があるアプリケーションでは、スレッドとメモリの消費量が大幅に増加します。このため、単一のコンポーネントが原因でプログラム全体がボトルネックに陥り、プログラム全体のパフォーマンスに影響が出るのではないかと心配になります。しかし〜がある
Jetty:
2.継続利用 大量のユーザーリクエストと長時間の接続を処理するメカニズム。
さらに、Jetty は非常に優れたインターフェイスを設計しているため、Jetty Jetty の特定の実装がユーザーのニーズを満たせない場合、ユーザーは Jetty の一部の実装を簡単に変更して、Jetty を特別なアプリケーションのニーズに適合させることができます。
組み込みが簡単
public class JettyServer { public static void main(String[] args) { Server server = new Server(8080); server.setHandler(new DefaultHandler()); XmlConfiguration configuration = null; try { configuration = new XmlConfiguration( new FileInputStream("C:/development/Jetty/jetty-6.1.6rc0/etc/jetty.xml")); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (SAXException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } try { configuration.configure(server); server.start(); } catch (Exception e) { e.printStackTrace(); } } }
次に、Jetty Server がどのように起動されるかを分析しましょう。まず、Jetty の起動時に、このクラスが実際に HttpServer を継承していることに注目します。
サーバーを使用する場合、つまり、Jetty ルート ディレクトリのコマンド ラインから java -jar start.jar etc/jetty.xml と入力すると、ここに構成ファイルがあることに注意してください。
Jetty.xml は実行パラメータとして使用されます。このパラメータは、複数の XML 設定ファイルにすることもできます。実際、この設定ファイルは Struts を使用する場合と似ています。
struts-config.xml ファイルに、サーバーの実行に必要なコンポーネント (前のセクションの HttpServer など) を書き込みます。
この設定ファイルには、設定に必要なコンポーネントクラスを記述することができます。上記の方法でJettyサーバーを起動すると、Serverクラスのmainが呼び出されます。
メソッドを使用する場合、このエントリ メソッドは最初に Server クラスのインスタンスを構築し (実際には HttpServer も構築します)、インスタンスを作成する過程で XmlConfiguration を構築します。
クラス オブジェクトを使用してパラメーター構成ファイルを読み取り、この構成ファイルによって生成された XmlConfiguration オブジェクトを使用してサーバーを構成します。構成プロセスでは実際に Java が使用されます。
リフレクション メカニズム。Server メソッドを呼び出し、構成ファイルに記述されたパラメータを渡してこの Server に追加します。
HttpListener、HttpContext、HttpHandler、および Web アプリケーション (Web アプリケーションに対応)。
-------------------------------------------- --- ----------------------------------
讨论 Jetty 的 Continuation 机制,首先需要提到 Ajax 技术,Ajax 技术是当前开发 Web 应用的非常热门的技术,也是 Web 2.0 的一个重要的组成部分。Ajax 技术中的一个核心对象是 XMLHttpRequest 对象,这个对象支持异步请求,所谓异步请求即是指当客户端发送一个请求到服务器的时候,客户端不必一直等待服务器的响应。这样就不会造成整个页面的刷新,给用户带来更好的体验。而当服务器端响应返回时,客户端利用一个 Javascript 函数对返回值进行处理,以更新页面上的部分元素的值。但很多时候这种异步事件只是在很小一部分的情况下才会发生,那么怎么保证一旦服务器端有了响应之后客户端马上就知道呢,我们有两种方法来解决这个问题,一是让浏览器每隔几秒请求服务器来获得更改,我们称之为轮询。二是服务器维持与浏览器的长时间的连接来传递数据,长连接的技术称之为 Comet。
大家很容易就能发现轮询方式的主要缺点是产生了大量的传输浪费。因为可能大部分向服务器的请求是无效的,也就是说客户端等待发生的事件没有发生,如果有大量的客户端的话,那么这种网络传输的浪费是非常厉害的。特别是对于服务器端很久才更新的应用程序来讲,比如邮件程序,这种浪费就更是巨大了。并且对 Server 端处理请求的能力也相应提高了要求。如果很长时间才向 Server 端发送一次请求的话,那么客户端就不能的得到及时的响应。
如果使用 Comet 技术的话,客户端和服务器端必须保持一个长连接,一般情况下,服务器端每一个 Servlet 都会独占一个线程,这样就会使得服务器端有很多线程同时存在,这在客户端非常多的情况下也会对服务器端的处理能力带来很大的挑战。
Jetty 利用 Java 语言的非堵塞 I/O 技术来处理并发的大量连接。 Jetty 有一个处理长连接的机制:一个被称为 Continuations 的特性。利用 Continuation 机制,Jetty 可以使得一个线程能够用来同时处理多个从客户端发送过来的异步请求,下面我们通过一个简化的聊天程序的服务器端的代码来演示不使用 Continuation 机制和使用 Continuation 的差别。
清单 2. Continuation 机制
public class ChatContinuation extends HttpServlet{ public void doPost(HttpServletRequest request, HttpServletResponse response){ postMessage(request, response); } private void postMessage(HttpServletRequest request, HttpServletResponse response) { HttpSession session = request.getSession(true); People people = (People)session.getAttribute(session.getId()); if (!people.hasEvent()) { Continuation continuation = ContinuationSupport.getContinuation(request, this); people.setContinuation(continuation); continuation.suspend(1000); } people.setContinuation(null); people.sendEvent(response); } }
大家注意到,首先获取一个 Continuation 对象,然后把它挂起 1 秒钟,直到超时或者中间被 resume 函数唤醒位置,这里需要解释的是,在调用完 suspend 函数之后,这个线程就可处理其他的请求了,这也就大大提高了程序的并发性,使得长连接能够获得非常好的扩展性。
如果我们不使用 Continuation 机制,那么程序就如 清单 3 所示:
清单 3. 不使用 Continuation 机制
public class Chat extends HttpServlet{ public void doPost(HttpServletRequest request, HttpServletResponse response){ postMessage(request, response); } private void postMessage(HttpServletRequest request, HttpServletResponse response) { HttpSession session = request.getSession(true); People people = (People)session.getAttribute(session.getId()); while (!people.hasEvent()) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } people.setContinuation(null); people.sendEvent(response); } }
大家注意到在等待事件发生的时间里,线程被挂起,直到所等待的事件发生为止,但在等待过程中,这个线程不能处理其他请求,这也就造成了在客户端非常多的情况下服务器的处理能力跟不上的情况。下面我们解释一下 Jetty 的 Continuation 的机制是如何工作的。
为了使用 Continuatins,Jetty 必须配置为使用它的 SelectChannelConnector 处理请求。这个 connector 构建在 java.nio API 之上,允许它维持每个连接开放而不用消耗一个线程。当使用 SelectChannelConnector 时,ContinuationSupport.getContinuation() 提供一个 SelectChannelConnector.RetryContinuation 实例(但是,您必须针对 Continuation 接口编程)。当在 RetryContinuation 上调用 suspend() 时,它抛出一个特殊的运行时异常 -- RetryRequest,该异常传播到 servlet 外并且回溯到 filter 链,最后被 SelectChannelConnector 捕获。但是不会发送一个异常响应给客户端,而是将请求维持在未决 Continuations 队列里,则 HTTP 连接保持开放。这样,用来服务请求的线程返回给 ThreadPool,然后又可以用来服务其他请求。暂停的请求停留在未决 Continuations 队列里直到指定的过期时间,或者在它的 Continuation 上调用 resume() 方法。当任何一个条件触发时,请求会重新提交给 servlet(通过 filter 链)。这样,整个请求被"重播"直到 RetryRequest 异常不再抛出,然后继续按正常情况执行。
--------------------------------------------------------------------------------
Jetty 的安全性
为了防止任何人都有权限去关闭一个已经开启的 Jetty 服务器, 我们可以通过在启动 Jetty
服务器的时候指定参数来进行控制,使得用户必须提供密码才能关闭 Jetty 服务器,启动 Jetty 服务器的命令如下所示:
java -DSTOP.PORT=8079 -DSTOP.KEY=mypassword -jar start.jar
这样,用户在停止 Jetty
服务器的时候,就必须提供密码“mypassword”。
--------------------------------------------------------------------------------
总结
Jetty 是一个非常方便使用的 Web 服务器,它的特点在于非常小,很容易嵌入到我们的应用程序当中,而且针对 Web 2.0 的 Ajax
技术进行了特别的优化,这也使得我们的使用 Ajax 的应用程序可以拥有更好的性能。
以上就是jetty的使用详解,更多相关文章请关注PHP中文网(www.php.cn)!