2

Nginx は、複数のクライアントを処理するために epoll またはその他の多重化手法 (選択) を使用します。つまり、apache とは異なり、リクエストごとに新しいスレッドを生成しません。

selectを使用して、自分のテストプログラムで同じことを複製しようとしました。ノンブロッキング ソケットを作成し、select を使用してサービスを提供するクライアントを決定することで、複数のクライアントからの接続を受け入れることができました。私のプログラムは、単にデータをエコーバックするだけです。小さなデータ転送(クライアントごとに数バイト)では問題なく動作します。

この問題は、クライアントへの接続を介して大きなファイルを送信する必要があるときに発生します。ファイルの読み取りとソケットへの書き込みが完了するまで、すべてのクライアントにサービスを提供するスレッドが1つしかないため、他のクライアントのサービスを再開できません。

この問題に対する既知の解決策はありますか、それともそのようなリクエストごとにスレッドを作成するのが最善ですか?

4

4 に答える 4

6

select を使用する場合、ファイル全体を一度に送信しないでください。たとえば sendfile を使用してこれを行う場合、ファイル全体が送信されるまでブロックされます。代わりに小さなバッファを使用し、一度に少量のデータを各クライアントに送信します。次に、select を使用して、ソケットが再び書き込み可能になったことを特定し、すべてのデータが送信されるまでさらに送信します。これにより、複数のクライアントを並行して処理できます。

于 2010-06-02T08:41:56.730 に答える
4

最も単純なアプローチは、リクエストごとにスレッドを作成することですが、これは確かに最もスケーラブルなアプローチではありません。現時点では、基本的にすべての高性能 Web サーバーが、epoll (Linux)、kqueue (BSD)、IOCP (Windows) などに基づいて構築されたさまざまな非同期アプローチを使用していると思います。

パフォーマンス要件に関する情報を提供しておらず、すべての非スレッド化アプローチでは、これらの複雑な非同期手法を使用するようにアプリケーションを再構築する必要があるため ( C10K の記事 やそこから見つけた他の記事で説明されているように)、今のところ、最善の策は、スレッド化されたアプローチを使用することです。

さらに必要な場合は、パフォーマンスの具体的な要件やその他の関連データで質問を更新してください。

于 2010-04-13T19:49:20.097 に答える
2

背景については、http: //www.kegel.com/c10k.html を読むと役立つ場合があります。

于 2010-03-30T04:13:19.200 に答える
0

単一の接続を処理するためにコールバックを使用していると思います。これは設計された方法ではありません。コールバックは、提供する予定の何千もの接続を処理する必要があります。つまり、パラメーターとして取得するファイル記述子の数から、(グローバル変数を読み取ることによって) そのクライアントをどうするかを知る必要があります。 )またはsend()または...何でも

于 2011-09-02T21:19:47.437 に答える