WebFlux WebClient 在分段上传期间将整个文件加载到直接缓冲区内存中
WebFlux WebClient loading entire file into direct buffer memory during multipart upload
我正在使用 Spring Boot 2.1.6.RELEASE & Webflux
构建应用程序
我们有一个可以使用 multipart 上传文件的端点,我们正在使用 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) 时,我们看到整个文件都被加载到直接内存中:
随着文件上传,内存被释放,然后当下一个文件上传时,您可以再次看到内存峰值。
相比之下,我尝试用 https://github.com/AsyncHttpClient/async-http-client 替换 WebClient 并且内存使用率低得多,每次上传约 60mb
当 WebFlux 客户端适用于我们所有其他用途时,我真的不想引入另一个 http 客户端依赖项。
这是 Spring 框架中的错误 - https://github.com/spring-projects/spring-framework/issues/23518
我正在使用 Spring Boot 2.1.6.RELEASE & Webflux
构建应用程序我们有一个可以使用 multipart 上传文件的端点,我们正在使用 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) 时,我们看到整个文件都被加载到直接内存中:
随着文件上传,内存被释放,然后当下一个文件上传时,您可以再次看到内存峰值。
相比之下,我尝试用 https://github.com/AsyncHttpClient/async-http-client 替换 WebClient 并且内存使用率低得多,每次上传约 60mb
当 WebFlux 客户端适用于我们所有其他用途时,我真的不想引入另一个 http 客户端依赖项。
这是 Spring 框架中的错误 - https://github.com/spring-projects/spring-framework/issues/23518