Java DataBufferLimitException:超出缓冲区webflux的最大字节数限制错误
发送文件时,我收到一个字节数组。我总是遇到webflux接收数组的问题。 引发的错误如下所示:Java DataBufferLimitException:超出缓冲区webflux的最大字节数限制错误,java,spring,webclient,spring-webflux,Java,Spring,Webclient,Spring Webflux,发送文件时,我收到一个字节数组。我总是遇到webflux接收数组的问题。 引发的错误如下所示: org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144 at org.springframework.core.io.buffer.LimitedDataBufferList.raiseLimitException(LimitedDat
org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
at org.springframework.core.io.buffer.LimitedDataBufferList.raiseLimitException(LimitedDataBufferList.java:101)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException
您现在知道如何在webflux中解决这个问题了吗?我想这个问题是关于在spring Boot中添加一个新的spring.codec.max-in-memory-size配置属性。将其添加到属性中,如:
spring:
codec:
max-in-memory-size: 10MB
在spring boot配置文件中设置最大字节数(在兆字节数中),如下所示:
spring.codec.max-in-memory-size=20MB
我在一个简单的RestController中遇到了这个错误(我发布了一个大的json字符串) 下面是我如何成功更改
maxInMemorySize
import org.springframework.context.annotation.Configuration;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.config.ResourceHandlerRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;
@Configuration
public class WebfluxConfig implements WebFluxConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui.html**")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024);
}
}
这对我来说是很难找到的
@Bean
public WebClient getWebClientBuilder(){
return WebClient.builder().exchangeStrategies(ExchangeStrategies.builder()
.codecs(configurer -> configurer
.defaultCodecs()
.maxInMemorySize(16 * 1024 * 1024))
.build())
.build();
}
@RestController / @Bean/ @Service
public class PaySharpGatewayController {
@Autowired
WebClient webClient;
public void test(){
String out = webClient
.get()
.uri("end point of an API")
.retrieve()
.bodyToMono(String.class)
.block();
sysout(out)
}
您可以流式传输以下内容,而不是一次检索数据:
Mono<String> string = webClient.get()
.uri("end point of an API")
.retrieve()
.bodyToFlux(DataBuffer.class)
.map(buffer -> {
String string = buffer.toString(Charset.forName("UTF-8"));
DataBufferUtils.release(buffer);
return string;
});
在大多数情况下,您不希望真正聚合流,而不是直接处理它。需要在内存中加载大量数据,这在很大程度上是将这种方法转变为更被动的方法的标志。JSON和XML解析器具有流式接口。另一种选择是创建自定义的
codecustomizer
,它将同时应用于WebFlux
和WebClient
:
@配置
类MyAppConfiguration{
伴星{
私有常量val MAX_MEMORY_SIZE=50*1024*1024//50 MB
}
@豆子
有趣的CodeCustomizer():CodeCustomizer{
返回编解码器自定义程序{
it.defaultCodecs()
.maxInMemorySize(最大内存大小)
}
}
}
这对我很有效
val exchangeStrategies = ExchangeStrategies.builder()
.codecs { configurer: ClientCodecConfigurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024) }.build()
return WebClient.builder().exchangeStrategies(exchangeStrategies).build()
webTestClient.mutate().codecs(configurer -> configurer
.defaultCodecs()
.maxInMemorySize(16 * 1024 * 1024)).build().get()
.uri("/u/r/l")
.exchange()
.expectStatus()
.isOk()
为我工作
val exchangeStrategies = ExchangeStrategies.builder()
.codecs { configurer: ClientCodecConfigurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024) }.build()
return WebClient.builder().exchangeStrategies(exchangeStrategies).build()
webTestClient.mutate().codecs(configurer -> configurer
.defaultCodecs()
.maxInMemorySize(16 * 1024 * 1024)).build().get()
.uri("/u/r/l")
.exchange()
.expectStatus()
.isOk()
谢谢,这是因为我在我的spring boot应用程序配置中使用了它,但是它没有帮助。@mareck_ste Hi!可能您正在使用一些覆盖此选项的自定义配置。例如,您有WebClient配置,所以只需在WebClient Builder.ExchangeStrages()@mareck_ste中设置此“maxInMemorySize”属性即可。事实上,我对spring boot starter webflux 2.3.5-RELEASE也有相同的配置。看看这里,缓冲区是在哪里定义的?@AshokKoyi我之前混淆了两个变量(已修复)您实际测量了总体内存占用吗?i、 e即使在释放数据缓冲区之后,除非您使用最后一个流,否则内存仍然会堆积,因为您正在使用reduce,直到收到最后一个字节。因此,我不确定使用这种方法是否会有任何优势选项(1)有问题,因为不能保证在将字节转换为字符串之前收到所有数据。在映射操作期间,我们可能只读取4字节UTF-8字符中的1字节。如果可以利用部分数据&释放缓冲区,这是最好的办法。使用归约是一个坏主意,因为我们正在填充内存,直到完成归约,这就破坏了在缓冲区出现时使用缓冲区的意义。选项(1)是有效的,但它只作为字节数组,而不是字符串数组。我不知道为什么,这是在WebFlux 2.3.2.RELEASE上工作的唯一解决方案