如果可能,您不应将要提供的文件的全部内容存储在内存中。相反,获取数据的 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 页面包含指向您的 webapp 的下载链接
- 用户点击下载链接
- 您的 web 应用程序会生成一个 S3 URL,其中包含一个在 5 分钟后到期的密钥。
- 使用步骤 3 中的 URL 向客户端发送 HTTP 重定向。
- 用户从 S3 下载文件。即使下载需要超过 5 分钟,这也有效 - 一旦下载开始,它可以继续完成。