【问题标题】:Webflux upload large files cause Java heap spaceWebflux上传大文件导致Java堆空间
【发布时间】:2023-04-08 12:30:01
【问题描述】:

可能没有多少开发人员和我一样面临同样的问题。
但我想分享我已经解决了将近 1 个月的解决方案。
我使用Kubernetes和docker-compose,这个Webflux服务(容器)设置内存限制1g mem_limit: 1g我不允许增加内存限制。

coRouter 已被用作容器中的控制器。

@Configuration
class WebController(
) {

    @Bean
    fun endpoints() = coRouter {
        contentType(MediaType.MULTIPART_FORM_DATA).nest {
            POST("/uploadFile") { requestParm ->
                requestParm.awaitMultipartData().multipartFormData["file"]?.first()
            }
        }
    }
}

如果我使用 API 上传文件 http://localhost:9004/uploadFile 100MB,10 个文件(使用 JS Ajax)
它将产生java.lang.OutOfMemoryError: Java heap space,因为它没有足够的内存。
每当您调用 requestParm.awaitMultipartData() 时,它都会将这些字节流式传输到内存中。

【问题讨论】:

    标签: spring-webflux large-files


    【解决方案1】:

    我意识到,我当前的代码会将上传文件直接存储在内存中。 有两种方法可以解决这个问题。

    • 第一种方式,在路由器或控制器上添加@EnableWebFlux
    
    @Configuration
    @EnableWebFlux
    class WebController(
    ) { }
    
    @Configuration
    class WebController(
    ): DelegatingWebFluxConfiguration() { }
    

    为什么解决了上传大文件的问题?

    上面这2种方式会自动被超类的方法使用
    configureHttpMessageCodecs(configurer: ServerCodecConfigurer)

    https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-codecs-multipart

    默认情况下,使用 DefaultPartHttpMessageReader,但这可以通过 ServerCodecConfigurer 进行更改。有关 DefaultPartHttpMessageReader 的更多信息,请参阅 DefaultPartHttpMessageReader 的 javadoc。

    如您所见,ServerCodecConfigurer 默认使用 DefaultPartHttpMessageReader。

    DefaultPartHttpMessageReader 有这个重要的属性MaxInMemorySize(如果内存已满,则存储在磁盘中)

    https://docs.spring.io/spring-framework/docs/5.3.1/javadoc-api/org/springframework/http/codec/multipart/DefaultPartHttpMessageReader.html#setMaxInMemorySize-int-

    配置每个部件允许的最大内存量。超出限制时: 文件部分被写入临时文件。 非文件部分被 DataBufferLimitException 拒绝。 默认设置为 256K。

    上传文件的默认内存是256K
    如果内存已满,它会将这些文件临时保存到磁盘。

    您也可以自定义内存以存储大小文件Spring WebFlux: set max file(s) size for uploading files

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 2013-05-03
      • 1970-01-01
      • 1970-01-01
      • 2016-03-28
      • 1970-01-01
      • 1970-01-01
      • 2018-05-21
      相关资源
      最近更新 更多