如果可能,不应将要提供的文件的全部内容存储在内存中。相反,请为数据获取 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 的“额外”内存用于提供图像数据。在谷歌的帮助下,“256MB / 200KB”= 1310。对于2GB的“额外”内存(现在是非常合理的数量),可以支持超过10,000个并发客户端。即便如此,1300 个并发客户端仍然是一个相当大的数字。这是您遇到的负载类型吗?如果没有,您可能需要在其他位置查找 OOM 异常的原因。
编辑 - 关于:
在此用例中,图像可能包含敏感数据...
几周前,当我通读 S3 文档时,我注意到您可以生成可附加到 S3 URL 的过期密钥。因此,您不必向公众打开S3上的文件。我对这项技术的理解是:
- 初始 HTML 页面包含指向您的 Web 应用的下载链接
- 用户点击下载链接
- 您的 Web 应用会生成一个 S3 URL,其中包含一个密钥,该密钥将在 5 分钟后过期。
- 使用步骤 3 中的 URL 向客户端发送 HTTP 重定向。
- 用户从 S3 下载文件。即使下载时间超过5分钟,这也有效 - 下载开始后,它可以继续完成。