DataBufferLimitException:버퍼 webflux 오류에 대한 최대 바이트 제한을 초과했습니다.
파일을 보내는 동안 바이트 배열을 받습니다.어레이를 받기 위해 항상 webflux에 문제가 있습니다.에러는 다음과 같습니다.
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로 해결하는 방법을 알 수 있습니까?
이 방법은 효과가 있었습니다.
작성하다
@Bean메인 「」의 어느 로,SpringBootApplication링크:@Bean public WebClient webClient() { final int size = 16 * 1024 * 1024; final ExchangeStrategies strategies = ExchangeStrategies.builder() .codecs(codecs -> codecs.defaultCodecs().maxInMemorySize(size)) .build(); return WebClient.builder() .exchangeStrategies(strategies) .build(); }다음, 여러분이 .
WebClient:@Service public class TestService { @Autowired private WebClient webClient; public void test() { String out = webClient .get() .uri("/my/api/endpoint") .retrieve() .bodyToMono(String.class) .block(); System.out.println(out); } }
는 새로운 합니다.spring.codec.max-in-memory-sizeSpring Boot (스프링 부트)에다가 더해요.application.yml다음과 같이 합니다.
spring:
codec:
max-in-memory-size: 10MB
스프링 부트의 최대 바이트(MB)를 설정합니다. application.properties다음과 같이 합니다.
spring.codec.max-in-memory-size=20MB
단순한 Rest Controller에서 이 오류가 발생하고 있습니다(큰 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);
}
}
이것은 의외로 찾기 어려웠다
나를 위해 일했다
webTestClient.mutate()
.codecs(configurer -> configurer
.defaultCodecs()
.maxInMemorySize(16 * 1024 * 1024))
.build().get()
.uri("/u/r/l")
.exchange()
.expectStatus()
.isOk()
데이터를 한 번에 검색하는 대신 다음과 같이 스트리밍할 수 있습니다.
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;
});
또는 스트림으로 변환:
.map(b -> b.asInputStream(true))
.reduce(SequenceInputStream::new)
.map(stream -> {
// consume stream
stream.close();
return string;
});
대부분의 경우 스트림을 직접 처리하지 않고 실제로 집약하고 싶지 않습니다.대량의 데이터를 메모리에 로드해야 하는 것은 대부분 접근 방식을 보다 반응적인 접근 방식으로 바꾸려는 신호입니다.JSON 및 XML-Pars에는 스트리밍 인터페이스가 있습니다.
이건 내게 효과가 있었다.
val exchangeStrategies = ExchangeStrategies.builder()
.codecs { configurer: ClientCodecConfigurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024) }.build()
return WebClient.builder().exchangeStrategies(exchangeStrategies).build()
하나의 은 관습이다를 만드는 입니다.CodecCustomizer 가지 할 수 있습니다.WebFlux ★★★★★★★★★★★★★★★★★」WebClient★★★★★★★★★★★★★★★★★★:
@Configuration
class MyAppConfiguration {
companion object {
private const val MAX_MEMORY_SIZE = 50 * 1024 * 1024 // 50 MB
}
@Bean
fun codecCustomizer(): CodecCustomizer {
return CodecCustomizer {
it.defaultCodecs()
.maxInMemorySize(MAX_MEMORY_SIZE)
}
}
}
Spring Boot 2.3.0에서는 Reactive Elasticsearch REST 클라이언트 전용 설정 속성이 있습니다.
다음 구성 속성을 사용하여 클라이언트의 특정 메모리 제한을 설정할 수 있습니다.
spring.data.data.search.client.spring.max-in-memory-size=기존 spring.spring.disc.max-in-memory-size 속성은 분리되어 있으며 응용 프로그램의 다른 WebClient 인스턴스에만 영향을 줍니다.
하기 위해 할 수 는 콩 하십시오.WebFluxConfigurationSupport를 사용하고 있는 는, 내, Boot 2.7.2에서는 스프링이 되는 「스프링을 로드합니다.spring.codec.max-in-memory-size이 솔루션이 동작하려면 , 이 속성도 올바르게 설정되어 있을 필요가 있습니다.
이것이 문제의 원인인지 여부를 테스트하려면WebFluxConfigurationSupport임시로 구현합니다.장기적으로는 Configuration bean을 사용하여 auto configured bean의 Atribute를 덮어쓰는 것이 효과가 있었습니다.저 같은 경우에는WebFluxConfigurer같은 방법을 모두 사용할 수 있어 의 대체 수단이었다.WebFluxConfigurationSupport큰 JSON 메시지가 설정대로 디코딩됩니다.
webClient 기본 설정을 글로벌하게 변경하지 않으려면 다음 방법을 사용하여 여러 DataBuffer를 수동으로 병합할 수 있습니다.
webClient
.method(GET)
.uri("<uri>")
.exchangeToMono(response -> {
return response.bodyToFlux(DataBuffer.class)
.switchOnFirst((firstBufferSignal, responseBody$) -> {
assert firstBufferSignal.isOnNext();
return responseBody$
.collect(() -> requireNonNull(firstBufferSignal.get()).factory().allocateBuffer(), (accumulator, curr) -> {
accumulator.ensureCapacity(curr.readableByteCount());
accumulator.write(curr);
DataBufferUtils.release(curr);
})
.map(accumulator -> {
final var responseBodyAsStr = accumulator.toString(UTF_8);
DataBufferUtils.release(accumulator);
return responseBodyAsStr;
});
})
.single();
});
위의 코드는 모든 데이터를 집약합니다.DataBuffers는 싱글로DataBuffer그 후, 최종 결과를 변환DataBuffer끈으로 묶다.수신된 DataBuffer가 문자를 구성하는 데 모든 바이트를 가지고 있지 않을 수 있으므로 이 답변은 작동하지 않습니다(UTF-8 문자를 포함하면 각 문자가 최대 4바이트를 차지할 수 있습니다).따라서 중간값으로 변환할 수 없습니다.DataBuffer를 String으로 변환합니다.버퍼의 끝에 오는 바이트는 유효한 문자를 작성하는데 필요한 바이트의 일부만 포함할 수 있습니다.
그러면 모든 응답이 로드됩니다.DataBuffer를 메모리에 저장하지만 글로벌 설정을 변경하는 것과는 달리webClient전체 어플리케이션에서 사용할 수 있습니다.이 옵션을 사용하면 원하는 부분만 전체 응답을 읽을 수 있습니다. 즉, 큰 응답이 예상되는 부분만 좁혀서 이 옵션을 선택할 수 있습니다.
Spring boot 2.7.x에서 메모리 크기를 webclient로 설정하려면 다음 속성을 사용해야 합니다.webclient는 반응형 Elastic Search에서 내부적으로 사용됩니다.
spring.elasticsearch.webclient.max-in-memory-size=512MB
springboot 메인클래스에 아래 코드를 추가합니다.
@Bean
public WebClient getWebClient() {
return WebClient.builder()
.baseUrl("Your_SERVICE_URL")
.codecs(configurer -> configurer
.defaultCodecs()
.maxInMemorySize(16 * 1024 * 1024))
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
}
난 이게 좋아.
언급URL : https://stackoverflow.com/questions/59735951/databufferlimitexception-exceeded-limit-on-max-bytes-to-buffer-webflux-error
'programing' 카테고리의 다른 글
| 문자열이 jq의 유효한 JSON인지 확인합니다. (0) | 2023.04.04 |
|---|---|
| Lombok - java.lang.StackOverflowError: toString 메서드의 null입니다. (0) | 2023.04.04 |
| 카테고리에 따라 제품별로 WooCommerce에 요금 추가 (0) | 2023.04.04 |
| 오류: 테이블 "tablename"의 업데이트 또는 삭제가 외부 키 제약 조건을 위반합니다. (0) | 2023.04.04 |
| 새 프로젝트의 경우 angularJs vs angular 2 (0) | 2023.04.04 |