使用 Spring RestTemplate 发送 1GB 二进制文件时处理 OOM 问题

问题描述 投票:0回答:1

在我的应用程序中,我们从数据库读取超过 100 万行。使用 Jdbc ResultSet 以流式方式将此数据存储在 Csv 文件中。 OpenCsv 库用于创建使用 ZipOutputStream 压缩的 CSV 文件。现在我想将此文件发送到另一个微服务。我为此使用 Spring RestTemplate。问题是,在执行 post() 请求时,整个文件已加载到内存中,我们开始遇到 OutOfMemory 问题。我读过 RestTemplate 有分块传输模式,这将花费更多时间来发送数据,但内存消耗应该保持不变,因为它不会在内存中缓冲整个数据。我正在尝试使用下面的代码,但看起来分块不起作用,我仍然注意到 OOM 并且内存消耗以相同的速率激增,我可以在 Grafana 上验证这一点。有什么办法可以管理这个要求吗?我正在分享我尝试过的代码,有人可以帮助我吗?我正在使用 springBoot 2.7 和 Java17,并且启用了 G1 GC。

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);

MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new FileSystemResource(""));

HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);

SimpleClientHttpRequestFactory httpRequestFactory = new SimpleClientHttpRequestFactory();
httpRequestFactory.setBufferRequestBody(false);
httpRequestFactory.setChunkSize(100);

RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(httpRequestFactory);

restTemplate.postForEntity(URI.create("myUrl"), requestEntity, String.class); 
java spring spring-mvc spring-resttemplate
1个回答
0
投票

我也遇到了同样的问题并遵循了解决方案, 但请求会产生

411 length required
错误,我猜是这样
BufferingClientHttpRequestFactory.class
未处理的请求 无法添加
content-length
标头,因为请求正文未在上下文中的任何位置进行缓冲。

有人对这个问题有任何线索吗?

© www.soinside.com 2019 - 2024. All rights reserved.