質問: サービス構成はJavaサーバ(apache/tomcat)、DBサーバ(postgresql)、画像サーバ(nginx)の基本3台構成の Webサービスです。 ユーザーの画像を登録できる仕組みが既に実装されており、 現状アップロードできる画像のファイルサイズは1MBですが、その上限を上げる予定です。 現状の画像生成はJavaサーバで下記の様に処理しています。 * formから取得した画像のバイト配列からFileOutputStreamでオリジナル画像生成(アップロード先:Javaサーバ) * ImageIO.readでオリジナル画像をアップロード先から読み込んでBufferedImageで受け取る(画像生成されているかどうかチェックも含む) * BufferedImageから5枚のサムネイル画像を生成してJavaサーバの画像ディレクトリに保存(アップロード先:Javaサーバ) * アップロード先ディレクトリ内の画像ファイルに更新があればそのファイルを画像サーバへ同期、 * クライアントからは画像サーバの画像を参照 このような処理では(特に)ImageIO.readがJavaのメモリをかなり消費してしまうようで、 メモリリーク等の可能性が懸念されたため、別の画像生成処理方法を検討しています。 そこで、いっそのことクライアントから画像をアップロードさせる時に、Javaサーバではなく画像サーバに直接アップロードさせて、 生成処理が完了したらDBサーバで保持している画像情報(更新日時や画像サイズなど)を更新するフローを考えています。 このフローに修正するとなると問題点やクリアしなければいけないことはもちろん色々と出てくるかもしれませんが、 やはり画像は画像サーバで生成処理をさせる方がJavaサーバのメモリも無駄にさせずに済みます。 画像アップロードの仕組みが実装されている比較的大規模なWebサービスではどのようなフローや構成なのでしょうか。
回答: > > (特に)ImageIO.readがJavaのメモリをかなり消費してしまうようで、メモリリーク等の可能性が懸念された > > > 「ImageIO memory leak」でWeb検索すると、結構な数の同じ悩みと解決法がみつかります。一度試されてみてはいかがでしょう。 また圧縮後データで1MBに制限されていても、(悪意をもってすれば)展開後が恐ろしく巨大な画像サイズになる攻撃用データを作ることが出来ます。このようなデータを素直に処理してしまうと、サーバサイドのメモリが枯渇したり、最悪サービス停止に陥る可能性があります。