22

このアプリケーションでは、1 秒あたり 5,000 リクエストを超えるリクエスト ボリュームを処理する必要があります。これは、私たちのタイプのアプリケーション (JSON-HTTP API をリモート システムに公開する必要がある場合) で Jetty を使用すると実現可能であると言われています。これにより、インバウンド リクエストと接続が開始されます。

数千のインバウンド HTTP 接続を受け取ります。それぞれの接続は永続的で、約 30 秒間続きます。次に、リモート サーバーは、これらの各接続で応答できる限り迅速に要求を送信します。30 秒後に接続が閉じられ、別の接続が開かれます。100 ミリ秒以内 (ネットワーク通過時間を含む) で応答する必要があります。

サーバーは EC2 で 8 GB の RAM を使用して実行され、そのうち 4 GB が Java VM に割り当てられます (過去の調査では、使用可能な RAM の半分以上を JVM に割り当てるべきではないことが示唆されています)。

Web で読んださまざまなヒントに基づいて、現在 Jetty を初期化する方法を次に示します。

Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(config.listenPort);
connector.setThreadPool(new QueuedThreadPool(5120));
connector.setMaxIdleTime(600000);
connector.setRequestBufferSize(10000);
server.setConnectors(new Connector[] { connector });
server.setHandler(this);
server.start();

当初、スレッドプールには 512 スレッドしかありませんでした。5120 に増やしてみましたが、これはあまり役に立ちませんでした。

このセットアップでは、毎秒 300 を超えるリクエストを処理するのに苦労しています。ハンドラーは簡単な計算と Gson シリアライゼーション/デシリアライゼーションを実行しているだけなので、問題はハンドラーにあるとは思いません。

この負荷を処理しようとしているときに独自の HTTP 要求を手動で実行すると、応答が始まるまでに数秒かかることがあります。

Jetty バージョン 7.0.0.pre5 を使用しています。

解決策、またはボトルネックを特定するためのテクニックについての提案をいただければ幸いです。

4

1 に答える 1

29

まず、Jetty 7.0.0.pre5 は非常に古いです。Jetty 9 がリリースされ、多くのパフォーマンスが最適化されています。

https://www.eclipse.org/jetty/previousversions.htmlで 7.x ラインの新しいバージョンをダウンロードし ます。

この次のアドバイスは、

必ずお読みください。

次に、スレッドプール サイズは、受け入れられた要求を処理するためのもので、512 は高くなっています。5120はばかげています。50 より大きく、500 より小さい数字を選択してください。

Linux ベースの EC2 ノードを使用している場合は、OS レベルで最大のメリットが得られるようにネットワークを構成してください。(詳細は上記リストの「高負荷」のドキュメントを参照)

Oracle Java 1.6u38 または 1.7u10 などの最新の JRE/JDK を使用していることを確認してください。また、64 ビット OS を使用している場合は、64 ビット JRE/JDK を使用してください。

アクセプタ カウントSelectChannelConnector.setAcceptors(int)を 1 ~ (number_of_cpu_cores - 1) の値に設定します。

最後に、最適化されたガベージ コレクションをセットアップし、GC ロギングをオンにして、問題が jetty にあるのか、Java の GC にあるのかを確認します。大規模な GC の "stop the world" イベントに多くの時間がかかっていることを GC ログで確認できた場合は、パフォーマンスの問題の原因がもう 1 つあります。

于 2013-01-09T23:31:36.953 に答える