可能であれば、提供するファイルの内容全体をメモリに保存しないでください。代わりに、データの InputStream を取得し、データを Servlet OutputStream に分割してコピーします。例えば:
ServletOutputStream out = response.getOutputStream();
InputStream in = [ code to get source input stream ];
String mimeType = [ code to get mimetype of data to be served ];
byte[] bytes = new byte[FILEBUFFERSIZE];
int bytesRead;
response.setContentType(mimeType);
while ((bytesRead = in.read(bytes)) != -1) {
out.write(bytes, 0, bytesRead);
}
// do the following in a finally block:
in.close();
out.close();
私は toby に同意します。代わりに、「S3 URL を参照する」必要があります。
OOM の例外についてですが、それは画像データの提供に関係していますか? JVM に、画像データの提供に使用する 256MB の「追加」メモリがあるとします。Google の助けを借りると、「256MB / 200KB」 = 1310 です。2GB の「追加」メモリ (最近では非常に妥当な量) の場合、10,000 を超える同時クライアントをサポートできます。それでも、1300 の同時クライアントはかなりの数です。これはあなたが経験した負荷のタイプですか?そうでない場合は、OOM 例外の原因を別の場所で探す必要があります。
編集 - について:
このユースケースでは、画像に機密データが含まれる可能性があります...
数週間前に S3 のドキュメントを読んだとき、S3 の URL に添付できる有効期限のあるキーを生成できることに気付きました。したがって、S3 上のファイルを公開する必要はありません。テクニックの私の理解は次のとおりです。
- 最初の HTML ページには、Web アプリケーションへのダウンロード リンクがあります
- ユーザーがダウンロード リンクをクリックする
- Web アプリケーションは、たとえば 5 分で有効期限が切れるキーを含む S3 URL を生成します。
- 手順 3 の URL を使用して HTTP リダイレクトをクライアントに送信します。
- ユーザーは S3 からファイルをダウンロードします。これは、ダウンロードに 5 分以上かかる場合でも機能します。ダウンロードが開始されると、完了まで続行できます。