我们的一个应用程序泄漏了文件句柄,我们还没有找到原因。
在代码中,我可以看到几个类似的函数:
public ResponseEntity<InputStreamResource> getFoo( ... ) {
InputStream content = getContent(...)
InputStreamResource isr = new InputStreamResource(content);
return ResponseEntity.status(HttpServletResponse.SC_OK).body(isr);
}
( if
检查和 try
/ catch
为简洁起见删除)
我确信这部分会导致问题,因为当我使用 JMeter 对这个特定代码进行负载测试时,我可以看到 getContent()
在这个阶段失败:
is = Files.newInputStream(f.toPath());
通常我会关闭 InputStream
但因为这个简短而简单的代码我无法在 return
或调用 body
之前关闭流。
当我运行 lsof
(代码在 Linux 上运行)时,我可以看到数千个文件以读取模式打开。所以我确信这个问题是由流没有关闭引起的。
是否有我应该交易的最佳实践代码?
原文由 Marged 发布,翻译遵循 CC BY-SA 4.0 许可协议
你可以尝试使用 StreamingResponseBody
因为您正在处理一个单独的线程,直接写入响应,所以您在
close()
return
问题已解决。也许您可以从以下示例开始
您也可以尝试使用
Files
(从java 7开始)所以你不必管理
InputStream
正如@Stackee007 在评论中描述的那样,在生产环境中的重负载下,为 — 定义一个
@Configuration
TaskExecutor
来调整参数和管理Async
过程。如何使用 mockMvc 进行测试
您可以在集成测试中简单地按照以下示例代码进行操作:
ResponseEntity<StreamingResponseBody>
的内容类型是MediaType.APPLICATION_OCTET_STREAM
在这个例子中,你可以得到 byte[] (.getContentAsByteArray()
)但是你可以得到所有内容的字符串/Json您的身体响应内容类型。