29

boost ::asioを使用してC++でミニHTTPサーバーを開発しましたが、現在、複数のクライアントで負荷テストを行っていますが、CPUの飽和状態に近づくことができませんでした。私はAmazonEC2インスタンスでテストしており、1つのCPUの約50%、別のCPUの20%を使用しており、残りの2つはアイドル状態です(htopによる)。

詳細:

  • サーバーはコアごとに1つのスレッドを起動します
  • リクエストは受信され、解析され、処理され、レスポンスは書き出されます
  • 要求は、メモリから読み取られるデータに対するものです(このテストでは読み取り専用)
  • それぞれがJavaアプリケーションを実行し、25スレッドを実行し、リクエストを送信する2台のマシンを使用してサーバーを「ロード」しています
  • 約230リクエスト/秒のスループットが見られます(これはアプリケーションリクエストであり、多くのHTTPリクエストで構成されています)

それで、この結果を改善するために私は何を見るべきですか?CPUがほとんどアイドル状態になっていることを考えると、その追加容量を活用して、たとえば800リクエスト/秒などのより高いスループットを実現したいと思います。

私が持っていたアイデア:

  • リクエストは非常に小さく、多くの場合数ミリ秒で実行されます。クライアントを変更して、より大きなリクエストを送信/作成することができます(おそらくバッチ処理を使用して)
  • Selectデザインパターンを使用するようにHTTPサーバーを変更できますが、これはここで適切ですか?
  • ボトルネックが何であるかを理解するために、いくつかのプロファイリングを行うことができます
4

6 に答える 6

46

boost::asio は期待するほどスレッドフレンドリーではありません - boost/asio/detail/epoll_reactor.hpp の epoll コードの周りに大きなロックがあり、一度に 1 つのスレッドしかカーネルの epoll syscall を呼び出せないことを意味します. そして、非常に小さなリクエストの場合、これはすべての違いになります (つまり、おおざっぱなシングルスレッドのパフォーマンスしか見られないということです)。

これは、boost::asio が Linux カーネル機能を使用する方法の制限であり、必ずしも Linux カーネル自体ではないことに注意してください。エッジ トリガー イベントを使用する場合、epoll syscall は複数のスレッドをサポートしますが、(過剰なロックなしで) 適切に行うのは非常に難しい場合があります。

ところで、私はこの分野でいくつかの作業を行っており (完全にマルチスレッド化されたエッジ トリガーの epoll イベント ループとユーザーがスケジュールしたスレッド/ファイバーを組み合わせています)、nginetdプロジェクトでいくつかのコードを利用できるようにしました。

于 2009-08-06T11:30:39.067 に答える
12

EC2 を使用しているため、すべての賭けはオフです。

実際のハードウェアを使用して試してみると、何が起こっているかを確認できる場合があります。VM でパフォーマンス テストを行うことは、基本的に不可能です。

EC2 が何に役立つかはまだわかっていません。誰かが見つけたら教えてください。

于 2009-08-06T12:59:37.173 に答える
3

このような単純な非同期リクエストの場合、230 リクエスト/秒は非常に低いようです。そのため、複数のスレッドを使用するのは最適化が時期尚早である可能性があります。適切に動作するようにし、単一のスレッドで調整して、それらがまだ必要かどうかを確認してください。不要なロックを取り除くだけで、物事がスムーズに進むかもしれません。

この記事には、2003 年頃の Web サーバー スタイルのパフォーマンスのための I/O 戦略に関する詳細と議論が含まれています。

于 2009-08-06T12:51:26.140 に答える