WebFlux WebClient 在分段上传期间将整个文件加载到直接缓冲内存中

Posted

技术标签:

【中文标题】WebFlux WebClient 在分段上传期间将整个文件加载到直接缓冲内存中【英文标题】:WebFlux WebClient loading entire file into direct buffer memory during multipart upload 【发布时间】:2019-12-15 02:54:19 【问题描述】:

我正在使用 Spring Boot 2.1.6.RELEASE 和 Webflux 构建应用程序

我们有一个端点,我们可以使用分段上传文件,并使用 WebClient 进行上传。

我们的上传客户端代码如下所示

@Component
class UploadClient(
    private val client: WebClient,
) 
    suspend fun upload(filePath: String) =
        client.post()
              .uri("/upload")
              .contentType(MULTIPART_FORM_DATA)   
              .body(BodyInserters.fromMultipartData(generateMultipartBody(filePath)))
              .retrieve()
              .bodyToMono(UploadResult::class.java)
              .awaitFirst()

    private fun generateMultipartBody(filePath: String): MultiValueMap<String, HttpEntity<*>> 
        val builder = MultipartBodyBuilder()
        builder.part("file", FileSystemResource(filePath))
        return builder.build()
    

但是,当我们上传一个大文件(1.6gb)时,我们会看到整个文件被加载到直接内存中:

随着文件上传,内存被释放,然后当下一个文件上传时,你可以再次看到内存中的峰值。

相比之下,我尝试将 WebClient 替换为 https://github.com/AsyncHttpClient/async-http-client,内存使用量要低得多,每次上传约 60mb

当 WebFlux 客户端适用于我们所有其他用途时,我真的不想引入另一个 http 客户端依赖项。

【问题讨论】:

也许您可以改为流式传输字节? 如何将 BodyInserters / MultipartBodyBuilder 与 WebFlux 结合使用? 这里是解决方案***.com/questions/64780779/… 【参考方案1】:

这是 Spring Framework 中的一个错误 - https://github.com/spring-projects/spring-framework/issues/23518

【讨论】:

以上是关于WebFlux WebClient 在分段上传期间将整个文件加载到直接缓冲内存中的主要内容,如果未能解决你的问题,请参考以下文章

为啥 WebFlux-WebClient 超时不起作用?

WebFlux系列WebClient 日志

Spring 5 webflux如何在Webclient上设置超时

Spring WebFlux WebClient 构建器设置请求正文

WebFlux系列WebClient 异常处理

WebFlux系列WebClient Post传参