3

私は、いくつかの異常な要件であると思われる Netty アプリをどのように設計するかを決定しようとしています。基本的に、リクエストを開始するクライアントがあります。この要求は英語に翻訳すると、「ディレクトリ /whatever/ の下にある小さな小さなファイルを再帰的に取得してください。それらのファイルについて私が言えることは、それらの名前が AAAAAAA.bin と CCCCCCC.bin の間にあるということだけです」となります。

したがって、サーバーはリクエストを受け取り、サーバー側でいくつかのディレクトリのスキャンを開始し、これらすべての小さなファイルを迅速にストリーミングし始める必要があります。パフォーマンスは重要ですが、AAAAAAA.bin と CCCCCCC.bin の間のすべてのファイルを受信したことを確認することも重要です。

では、クライアントとサーバー自体を基本的に非同期にするのは良い設計でしょうか? 言い換えると、クライアントは会話を開始し、リクエストを送信し、確認応答の UUID トークンなどを受け取るだけで、サーバーはファイル (おそらくスレッドごとに 1 つ) の収集を開始し、クライアントに連絡して、それに沿って 1 つのファイルを渡します。 UUIDで?クライアントは定期的にサーバーに「UUID トークン /sometoken/ に一致するリクエストのストリーミングを終了しましたか?」と尋ねることができると考えています。

クライアントとサーバーの両方が会話を開始するため、これがどのように構成されるかはよくわかりません。それとも、他の誰かがより良いデザインのアイデアを持っているのでしょうか? ここでも、パフォーマンス (要求の開始からすべてのファイル転送の完了までの合計時間) が重要です。

ありがとう!

4

1 に答える 1

1

プロトコルを完全に制御している (つまり、HTTP に限定されていない) と仮定すると、おそらく次のようになります。

  1. クライアントがサーバーに接続し、ディレクトリ要求を送信します。クライアントが中止された転送を再開している場合、2 からのトークンを使用してリクエストが送信されます。
  2. サーバーは、この転送に対して一意のトークンで応答します。転送が再開されている場合は、1 からのトークンで応答します。
  3. サーバーは、この転送のすべてのファイルを識別し、各ファイルに一意の ID を与え、ファイル セットを 2 のトークンに関連付けます (トークンを生成する前にファイルを把握する必要がある場合があります)。
  4. ファイルごとに、サーバーはファイル長、一意のファイル ID、ファイル (およびファイル名などのその他の情報) で構成されるメッセージを送信します。サーバーは各ファイルをできるだけ早く送信し、5 からの確認応答を待ちません。
  5. クライアントは、一意のファイル ID を使用して受信した各ファイルを確認します。
  6. 最後のファイルが送信された後、サーバーは「転送完了」メッセージを送信します。

上記の通信はすべて、1 つのチャネルで行われます。重要な点は、ファイルをストリーミングし、確認応答を非同期的に受信することで、ネットワークの遅延を軽減することです。

ファイルがたくさんある場合は、ファイルごとにスレッドを使用しません。おそらく、送信する各ファイルがジョブ キューに追加されるスレッド プール、または一意の各ディレクトリがジョブ キューに追加され、スレッドが一度にディレクトリを処理します。channel.write(..) への呼び出しを同期する必要がある場合があります。また、クライアントが順不同でファイルを受信して​​も問題ないと思います。

実際、最初はファイルを読み取るスレッドを 1 つだけ使用していました。確実に動作するようになったら、複数のスレッドを使用してネットワークをビジー状態に保つ (つまり、次のファイルの読み取りを待機しない) ことでパフォーマンスを向上できるかどうかを確認します。

チャネルに書き込むときは、おそらくファイルの詳細 (一意の ID、十分に小さい場合はファイル データ、必要に応じてファイル名) を含むオブジェクトに書き込み、オブジェクトをチャネル バッファとの間で変換できるコーデックを用意します。

正確な状況に応じて、クライアントはサーバーへの複数の接続を開くことができ、特定のファイル読み取りスレッドに接続を割り当てることができるため、チャネル同期の問題を回避できます。その方法でいくらかパフォーマンスが向上する可能性がありますが、ほとんどの場合、接続間で共有されている使用可能な帯域幅が表示されるだけです。

于 2012-08-03T15:45:54.060 に答える