0%

spring-cloud-gateway缓存区不够用的解决办法

前言

最近碰到一个问题,我们的Spring Cloud Gateway网关有个接口一直报错,错误堆栈如下:

1
2
3
4
5
6
org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
at org.springframework.core.io.buffer.LimitedDataBufferList.raiseLimitException(LimitedDataBufferList.java:98) ~[spring-core-5.2.12.RELEASE.jar!/:5.2.12.RELEASE]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ Body from UNKNOWN [DefaultClientResponse]
|_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]

看起来应该是有个DataBuffer缓冲区不够用,然后确认了下目标接口的响应报文确实有点大,于是乎开始 google 寻找答案。

解决办法

  1. 通过spring配置直接调整对应的内存大小
1
2
3
spring:
codec:
max-in-memory-size: 16MB
  1. 通过实现WebFluxConfigurer接口来配置
1
2
3
4
5
6
7
8
@Configuration
public class WebfluxConfig implements WebFluxConfigurer {

@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024);
}
}

如果是使用自定义的WebClient,那么需要这样配置:

1
2
3
4
5
6
7
8
@Bean
public WebClient getWebClientBuilder(){
return WebClient.builder()
.codecs(configurer -> configurer
.defaultCodecs()
.maxInMemorySize(16 * 1024 * 1024))
.build();
}

踩坑

通过上面两个办法配置之后,问题还是一直存在,后来发现是因为使用了手动构造的List<HttpMessageReader<?>>

1
2
3
4
@Bean
public List<HttpMessageReader<?>> messageReaders() {
return HandlerStrategies.withDefaults().messageReaders();
}

这种方式通过 Spring 配置的缓存区大小不会生效,后面改成通过ServerCodecConfigurer中来获取就 OK 了:

1
2
3
4
@Bean
public List<HttpMessageReader<?>> messageReaders(ServerCodecConfigurer codecConfigurer) {
return codecConfigurer.getReaders();
}

我是MonkeyWie,欢迎扫码👇👇关注!不定期在公众号中分享JAVAGolang前端dockerk8s等干货知识。

如果觉得本文对您有帮助,可以请我喝一杯咖啡☕