Jetty徹底解説 — 軽量Javaサーバーの特徴・組み込み利用・設定・運用ガイド

はじめに — Jettyとは何か

JettyはJavaで実装されたオープンソースのHTTPサーバー兼サーブレットコンテナです。軽量かつモジュール化された設計により、組み込み用途(アプリケーション内部に直接サーバーを組み込む形)やスタンドアロンなWebサーバーとして幅広く利用されています。開発元は当初Mort Bayで、その後Eclipse Foundationのプロジェクトとして継続されています。

歴史とバージョンの流れ

Jettyは長年にわたり進化を続けており、重要な節目としては「古いjavax.*名前空間を使う9系」から「Jakarta EE(jakarta.*)に移行した10/11系」への移行が挙げられます。近年のメジャーバージョンはJavaランタイムやJakarta Servlet仕様の進化に追随しており、Jetty 11以降は主にJava 11以降とJakarta名前空間を標準サポートします。実運用ではプロジェクトの要件に応じて9系(古いjavax API)と10/11系(Jakarta API)の選択が必要です。

アーキテクチャの概要

Jettyの設計はモジュール化と非同期I/Oに重点を置いています。主要な構成要素は以下の通りです。

  • Server:Jettyのエントリポイントで、コネクタやハンドラを管理します。
  • Connector(例:ServerConnector):TCP接続を受け付け、HTTPプロトコル処理へ橋渡しします。SSL/TLSはSslContextFactoryと組み合わせて行います。
  • Handler/ServletContainer:リクエストをハンドルするためのコンポーネント群。ContextHandler、ServletContextHandler、ResourceHandlerなどがあり、ルーティングや静的コンテンツ配信、Servlet APIの提供を担当します。
  • ThreadPool(例:QueuedThreadPool):リクエスト処理用のスレッド管理。軽量性とスループットのバランスをとるためにカスタマイズ可能です。
  • I/O層:Java NIO/NIO2をベースに非同期処理を行います。HTTP/2やWebSocketのためにALPNや専用コネクタを用いることができます。

主な特徴と強み

  • 組み込みが容易:数行のコードでアプリ内にJettyを組み込めるため、マイクロサービスやツールに適しています。
  • モジュール化:必要な機能だけを有効化でき、最小構成で軽快に動作します。
  • 非同期処理とスケーラビリティ:Servlet 3.x以降の非同期APIや内部の非同期I/Oにより、高負荷時の効率が高いです。
  • 最新プロトコルサポート:HTTP/2、WebSocket、TLS(最新の暗号やALPN)をサポートします。
  • 豊富な拡張性:ハンドラやコネクタを組み合わせ、独自の機能やミドルウェアを構築可能です。

組み込み利用(Embedding)

Jettyをライブラリとしてアプリに組み込む利用は非常にポピュラーです。代表的な簡単なサンプルは次のようになります(説明目的、実運用では例外処理や設定読み込みを行ってください)。

org.eclipse.jetty.server.Server server = new org.eclipse.jetty.server.Server(8080);
org.eclipse.jetty.servlet.ServletContextHandler ctx = new org.eclipse.jetty.servlet.ServletContextHandler();
ctx.setContextPath("/");
ctx.addServlet(HelloServlet.class, "/hello");
server.setHandler(ctx);
server.start();
server.join();

このように既存アプリに直接サーバーを組み込むことで、運用やデプロイの柔軟性が増します。Spring Bootなどのフレームワークも組み込みJettyをオプションとしてサポートしています。

設定と起動方式

Jettyは設定方法が複数あります。主な方法は次の通りです。

  • start.jar と start.d(モジュール)ベースの設定:スタンドアロン運用での標準的な管理方法。モジュール機構で機能を有効化/無効化できます。
  • XML設定ファイル:server.xmlなどのXMLで細かい設定が可能(従来のJetty設定方式)。
  • プログラムによる設定(API):組み込み利用時にJavaコードで直接サーバーやコネクタ、ハンドラを構築します。
  • プロパティ/環境変数:設定の注入や運用環境ごとの切り替えに利用されます。

TLS/セキュリティ設定のポイント

本番環境ではTLS(SSL)設定が不可欠です。JettyではSslContextFactoryを用いてキーストア/トラストストア、プロトコル(TLSv1.2/TLSv1.3)、および許可する暗号スイートを設定します。ALPN(Application-Layer Protocol Negotiation)を有効にするとHTTP/2をネゴシエートできます。

セキュリティ関連のベストプラクティス:

  • TLSは可能な限りTLS 1.3を優先し、古いプロトコルは無効化する。
  • 脆弱な暗号スイートを無効化し、強力なものに限定する。
  • 証明書の適切な管理(自動更新が必要ならACMEなど外部仕組みを検討)。
  • JettyのSecurityHandlerやServletフィルタを使った認証・認可の実装。
  • HTTPヘッダ(HSTS、Content-Security-Policy、X-Content-Type-Options等)の適切な設定。

HTTP/2とWebSocketのサポート

JettyはHTTP/2をサポートしており、ALPNを通じてクライアントとプロトコルのネゴシエーションを行います。HTTP/2の設定ではコネクタ側でHTTP/1.1とHTTP/2の両方を許可することが一般的です。

また、JettyはWebSocketの実装も提供しており、サーバー側での双方向通信を容易に扱えます。APIは標準のWebSocket仕様(javax.websocketまたはjakarta.websocket)に準拠しており、サーバーとクライアント双方の処理を行えます。

パフォーマンスとチューニング

Jettyのパフォーマンスを最大化するためのポイント:

  • スレッドプールのチューニング:QueuedThreadPoolの最小/最大スレッド数やキューサイズをアプリケーションの特性に合わせる。
  • 非同期処理の活用:長時間ブロッキングを避け、非同期Servletや非同期ハンドラでスループットを改善する。
  • コネクタの調整:Acceptor/Selectorスレッド数を調整し、接続数やCPUコア数に最適化する。
  • リソースキャッシュ:静的コンテンツはResourceHandlerやCDNでキャッシュし、負荷を軽減する。
  • HTTP/2の利用:多重化による効率化で小さな多数リクエストがある環境で効果を発揮する。

運用監視と管理

運用面では次の点を考慮します。

  • ログ出力:JettyはSLF4J等を通じたロギングに対応。アクセスログやエラーログを適切に設定する。
  • メトリクス:JMXやPrometheusエクスポーターを通じてスレッド、接続、リクエスト数などを監視する。
  • 可観測性:分散トレーシング(OpenTelemetry等)と組み合わせて遅延解析や障害分析を行う。
  • 稼働管理:start.jarのモジュール方式やOSのサービス(systemd等)での起動管理、コンテナ化(Docker/Kubernetes)による運用。

移行と互換性の注意点

Jettyのメジャーバージョン間で、特に名前空間(javax.からjakarta.への移行)やJavaの最低動作バージョンに関する互換性の差異があります。既存アプリケーションをJettyの新しいメジャーバージョンへ移行する際は、使用しているServlet/JSP/WebSocket APIの名前空間や依存ライブラリの対応状況を確認してください。また、サードパーティのライブラリがまだ旧名前空間に依存している場合、移行にはコード修正か変換ツール(Jakarta EE変換プラグイン等)が必要になることがあります。

よくあるユースケースと導入事例

Jettyは次のような用途で多く使われています。

  • マイクロサービスや軽量APIサーバー:組み込みが容易でデプロイが単純。
  • リアルタイム通信:WebSocketを使ったチャットや通知システム。
  • プロキシやゲートウェイのバックエンド:HTTP/2やTLS対応のフロントエンド。
  • 組み込み機器やエンタープライズツールの内部HTTPエンジン。

トラブルシューティングのヒント

  • コネクション不足やスレッド枯渇:スレッドプールやコネクタ設定を確認し、長時間ブロッキング処理の有無をチェックする。
  • TLSネゴシエーションの失敗:キーストア/トラストストア設定、ALPNサポート、JVMの暗号ポリシーを確認する。
  • パフォーマンス劣化:プロファイラやJMXでスレッド待ち・GCの影響・I/O待ちを解析する。
  • 互換性の問題:APIの名前空間(javax/jakarta)や依存ライブラリのバージョンを確認する。

導入判断のポイント

Jettyを選定する際は、以下を評価してください:

  • 組み込み要件の有無:アプリ内にサーバーを組み込みたいならJettyは有力な選択肢です。
  • プロトコル要件:HTTP/2やWebSocketのネイティブサポートが必要か。
  • 運用体制:コンフィグ管理や監視、証明書管理のポリシーに適合するか。
  • 互換性:既存のライブラリがjakarta移行に対応しているかを確認する。

まとめ

Jettyは軽量で拡張性が高いJavaベースのHTTPサーバー/サーブレットコンテナです。組み込み用途や高スループット、最新プロトコル対応を求めるシステムで有効に機能します。一方で、バージョン間の名前空間変更やJVM要件の違いに注意が必要です。導入時はTLS設定、スレッドプール、非同期処理の設計と監視体制を適切に整備することで、安定した運用が可能になります。

参考文献

Eclipse Jetty 公式サイト

Jetty Documentation

Jetty - Wikipedia

Jetty Javadoc