0

サーバーのクラスター (互いにリモートである可能性があります) があり、これらはすべてTomcatApache を使用して HTTP 経由で実行および通信しますHttpClient。これらのサーバーの多くはデータ ストアであり、サーバーの 1 つは、クライアントとストアの間の仲介者として機能する前面 Web サーバーです。ユーザーはファイルを Web サーバーにアップロードできる必要があり、Web サーバーはそのファイルを指定された数のストアに渡します。

質問: クライアントからのアップロードのファイル部分を取得し、ストアInputStreamへの複数のPOST要求に同時に書き込むことは可能ですか? 単純にローカル ファイルに書き込む場合、明らかな解決策は、のチャンクを配列バッファーに読み取りInputStreambyteバッファーから各出力に順番に書き込むことですが、HttpClient を納得させる方法について途方に暮れています。このようなストリームを「共有」します。

はい、単純に全体を Web サーバー上のオブジェクトに読み込んでInputStreamストアに順番に書き出すこともできますが、非常に大きなファイルを受け入れる可能性があるため、データをディスクに書き込んで読み戻す必要があります。ディスク操作の数がすぐに法外なものになる可能性があります。これは避けたい実装です。

4

2 に答える 2

0

店舗に追いつくためのネットワーク帯域幅がない場合、ストリームをどのように「共有」しますか?

着信ファイルを分割して、ディスクに書き込まずにストアに渡すことができますが、ストアの 1 つだけが追いつかない場合は、そのファイル データを受け入れられるまでメモリに保持する必要があります。大きなファイルまたは多くのユーザーの場合、すべてのメモリを使用する可能性があります。

より技術的に言えば、データをストアにできるだけ速く送信し、ファイル データを共有 FIFO 構造に保持する 5 つのスレッドを作成できるということです。最後のスレッドが部分にアクセスしてその部分を送信すると、そのデータはデータ構造から削除できますが、それ以前には削除できません。速度が遅いと、データ構造が巨大になる可能性があります。

メモリでもハードドライブでもない場合、データはどこかにある必要があります。

したがって、メモリが不足するまで (もし?) 受信データをメモリに保持し (絶対に?)、ハード ドライブにフラッシュします。データをストアに送信してから削除することにより、データでデータ構造を空にしようとし続けます。

データの再送信とデータ構造のクリーンアップを処理する ExecutorService をかなり簡単にコーディングできますが、魔法のように問題を解決することはできません。:)

あなたはこの解決策を望まないようなので、ソースコードを提供していません。ハードドライブにバッファリングする必要がなければ、魔法のようにデータを渡すことができないことを受け入れる場合は、後で実装するのに助けが必要になる場合があります (または、より悪い解決策は、ユーザーのアップロードを MinimumBandwidth(store1 、store2、store3、store4、store5))。

編集/変更:

私がそう言ったとしても、あなたが本当に ExecutorService を望んでいるかどうかはわかりません。これを実際に処理するために、独自のカスタム スレッドを作成します。おそらく、バイト配列(バイトではなく、バイトの配列)を保持するLinkedBlockingQueueである、並行パッケージからコレクションを作成します。次に、データを渡す際に各スレッドのプロセスの現在のインデックスを保持する Thread->Integer からマップを作成します。すべての進行状況の数値が 10 を超える場合 (つまり、すべてのスレッドが最初の 10 個のチャンクを送信したことを意味します)、最初の 10 バイト配列を削除し、すべてのスレッドの進行状況から 10 を引いてリセットします。

于 2013-08-12T14:51:08.273 に答える