解决常规请求大小限制问题
近日,在把文件上传接口放在 SpringCloudGateway 后发现偶尔上传文件失败问题,经过初步排查前端上传文件超过256KB就会出错,经过简单日志排查,发现是我们的网关问题,错误日志大致如下:
1 | org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144 |
发现是网关默认限制了请求Body的大小为 256KB,而我们则需要修改这个限制,经过网上查找资料,找到 How to Resolve Spring Webflux DataBufferLimitException 这篇文章,文章中的解决方式如下:
实现 WebFluxConfigurer
接口并重写 void configureHttpMessageCodecs(ServerCodecConfigurer)
方法,
1 |
|
以及在配置文件(application.yml
)中增加配置内容:
1 | spring: |
经过以上两个设置,就可以成功修改请求大小限制。
解决常规解决方案不生效问题
一般情况下,经过上面的处理,都可以成功的修改Gateway的请求限制,但是有时候他莫名其妙的失效了,在本次的错误处理中,我就遇到了这个问题。
最终经过排查,是我向Gateway增加了一个 RequestLogFilter
请求日志打印的全局过滤器导致的,在这个过滤器中,我手动创建了一个 XxxGatewayFilterFactory
对象,大致代码如下:
1 |
|
在上面的 RequestLogFilter
对象中,在初始化Bean阶段创建了 ModifyRequestBodyGatewayFilterFactory
对象,而在其构造方法中使用 HandlerStrategies.withDefaults().messageReaders()
创建了一个默认的 List<HttpMessageReader<?>>
,问题就是出在这个地方。
HandlerStrategies.withDefaults().messageReaders()
会创建一个默认的 ServerCodecConfigurer
对象,此对象负责初始化相关的 HttpMessageReader
对象,而这个环节中,HandlerStrategies
和 ServerCodecConfigurer
都无法读取我们前面配置的 maxInMemorySize
参数,此时 ServerCodecConfigurer#maxInMemorySize == null
,所以在初始化 HttpMessageReader
时无法设置正确的请求大小限制配置,并且最终系统启动完毕后,会直接使用此次创建的 List<HttpMessageReader<?>>
,直接导致后续所有的请求都无法突破 256KB 的限制。
实际最终的问题是,代码运行的过程中,手动创建 ServerCodecConfigurer
比 SpringBoot 初始化的 ServerCodecConfigurer
的时间早 ,导致了Gateway最终 codecConfigurer.getReaders()
得到的 List<HttpMessageReader<?>>
以第一个为准。
因此解决的方法也很简单,那就是使用 SpringBoot 初始化的 ServerCodecConfigurer
对象,或者我们创建 ServerCodecConfigurer
对象时手动设置其 maxInMemorySize
参数。
例如可参考如下解决方案:
1 |
|