报错信息
org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
at org.springframework.core.io.buffer.LimitedDataBufferList.raiseLimitException(LimitedDataBufferList.java:99)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
*__checkpoint ? springfox.boot.starter.autoconfigure.SwaggerUiWebFluxConfiguration$CustomWebFilter [DefaultWebFilterChain]
*__checkpoint ? org.springframework.web.cors.reactive.CorsWebFilter [DefaultWebFilterChain]
*__checkpoint ? org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
*__checkpoint ? org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
Original Stack Trace:
at org.springframework.core.io.buffer.LimitedDataBufferList.raiseLimitException(LimitedDataBufferList.java:99)
at org.springframework.core.io.buffer.LimitedDataBufferList.updateCount(LimitedDataBufferList.java:92)
at org.springframework.core.io.buffer.LimitedDataBufferList.add(LimitedDataBufferList.java:58)
at reactor.core.publisher.MonoCollect$CollectSubscriber.onNext(MonoCollect.java:119)
at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200)
at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
at reactor.netty.channel.FluxReceive.onInboundNext(FluxReceive.java:364)
at reactor.netty.channel.ChannelOperations.onInboundNext(ChannelOperations.java:404)
at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:595)
at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:93)
private void updateCount(int bytesToAdd) {
if (this.maxByteCount < 0) {
return;
}
if (bytesToAdd > Integer.MAX_VALUE - this.byteCount) {
raiseLimitException();
}
else {
this.byteCount += bytesToAdd;
if (this.byteCount > this.maxByteCount) {
raiseLimitException(); //报错地方
}
}
}
spring:
codec:
max-in-memory-size: 20MB 这个配置未生效。
检查拦截Request的代码filter:
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
if (HttpMethod.GET.matches(exchange.getRequest().getMethodValue())
|| HttpMethod.POST.matches(exchange.getRequest().getMethodValue())) {
ModifyRequestBodyGatewayFilterFactory.Config modifyRequestConfig = new ModifyRequestBodyGatewayFilterFactory.Config()
.setContentType(ContentType.APPLICATION_JSON.getMimeType())
.setRewriteFunction(String.class, String.class, (exchange1, originalRequestBody) -> {
//业务逻辑
return Mono.just(dataStr);
} catch (Exception e) {
return Mono.error(e);
}
});
return new ModifyRequestBodyGatewayFilterFactory()//这个地方出问题了
.apply(modifyRequestConfig)
.filter(exchange, chain)
.onErrorResume(e -> handleFilterError(exchange, e));
}
return chain.filter(exchange);
};
}
ModifyRequestBodyGatewayFilterFactory()这个构造底层实现如下
public ModifyRequestBodyGatewayFilterFactory() {
super(Config.class);
this.messageReaders = HandlerStrategies.withDefaults().messageReaders();
}
底层默认值:
修改方式
使用这个来构造并且引入以下bean,使得配置生效
@Autowired
ServerCodecConfigurer codecConfigurer;
spring.codec.max-in-memory-size配置说明
spring.codec.max-in-memory-size是Spring WebFlux中的一个配置参数,用于限制内存中的数据缓冲区大小。具体解释如下:
- 作用:控制在处理请求或响应时,Spring WebFlux使用的内存缓冲区的最大大小。用于防止应用程序因为大量数据导致内存消耗过高而崩溃。
- 配置方式:以字节为单位指定缓冲区的最大大小。可以在应用程序的配置文件(如application.properties或application.yml)中设置该参数。
- 默认值:如果未显式配置,则默认值为262144字节(即256KB)。
底层生效逻辑在类:CodecsAutoConfiguration
@Bean
@Order(0)
CodecCustomizer defaultCodecCustomizer(CodecProperties codecProperties) {
return (configurer) -> {
PropertyMapper map = PropertyMapper.get();
CodecConfigurer.DefaultCodecs defaultCodecs = configurer.defaultCodecs();
defaultCodecs.enableLoggingRequestDetails(codecProperties.isLogRequestDetails());
map.from(codecProperties.getMaxInMemorySize()).whenNonNull().asInt(DataSize::toBytes)
.to(defaultCodecs::maxInMemorySize);
};
}