6

それで、私がウェブサーバーを書いていて、「非常に大きな」ファイルのアップロードをサポートしたいとしましょう。さらに、標準の multipart/form-data MIME タイプを介してこれを行うつもりであると仮定しましょう。私は erlang を使用しており、http パケットが から返されるときに収集する予定であると言う必要がありますがerlang:decode_packet/2、http 要求ハンドラーがアップロードされたコンテンツの場所を見つけるまで、実際に要求本文を収集したくありません。するべきか

a) 本体が非常に大きく、メモリ不足のためにサーバーがクラッシュする可能性を無視して、とにかく本体を収集しますか?

b) ヘッダーが処理されるまで、(存在しない可能性がある) リクエストボディをソケットで受信することを控えますか?

c) 何か他のことをしますか?

回答 c の例としては、別のプロセスを生成して、アップロードされたコンテンツを収集して一時的な場所に書き込む (メモリの使用を最小限に抑えるため) と同時に、将来の処理のためにその場所を http リクエスト ハンドラーに提供します。しかし、私にはわかりません-ここに標準的なテクニックはありますか?

4

3 に答える 3

2

私の意見では、オプション b が明らかに優れています。

ソケットを読み取っていない間、TCP コードは受信データをカーネル内にバッファリングし続けます。そうするにつれて、最終的に (カーネルの TCP 受信バッファーがいっぱいになると)、TCP ウィンドウが閉じられるまで、HTTP サーバーにますます小さい TCP ウィンドウ サイズをアドバタイズします。

言い換えれば、ソケットを読み取らないことで、TCP フロー制御にその仕事を任せることになります。

于 2010-03-06T12:59:06.740 に答える
0

私の実装では、答えcの例を使用します-ソケットチャンクからチャンクごとに読み取り、チャンクを一時ファイルに保存します。また、afaik yaws も同様の手法を使用しています。yaws/src/yaws_multipart.erl で確認できます。

于 2010-03-04T07:31:35.060 に答える