I’m using WebClient from reactor-netty to call the downstream,
the downstream with latency is 15s to the response.
I’m trying to use Jmetter to send 20request per second, and half of them return 500 with WebClient timeout exception like below:
java.util.concurrent.TimeoutException: Webclient timeout
at********.Test.lambda$call$1(Test.java:37)
at reactor.core.publisher.Mono.lambda$onErrorResume$32(Mono.java:3887)
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94)
at reactor.core.publisher.SerializedSubscriber.onError(SerializedSubscriber.java:124)
at reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.handleTimeout(FluxTimeout.java:295)
at reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.doTimeout(FluxTimeout.java:280)
at reactor.core.publisher.FluxTimeout$TimeoutTimeoutSubscriber.onNext(FluxTimeout.java:419)
at reactor.core.publisher.FluxOnErrorReturn$ReturnSubscriber.onNext(FluxOnErrorReturn.java:162)
at reactor.core.publisher.MonoDelay$MonoDelayRunnable.propagateDelay(MonoDelay.java:271)
at reactor.core.publisher.MonoDelay$MonoDelayRunnable.run(MonoDelay.java:286)
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68)
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 20000ms in 'flatMap' (and no fallback has been configured)
... 13 common frames omitted
step reproduce:
using JMeter to send 20 requests/second into GET /test API
@RestController
@RequiredArgsConstructor
public class Test {
private final WebClient.Builder webClientBuilder;
public Mono<?> call() {
return webClientBuilder.build().method(HttpMethod.GET)
.uri("http://localhost:8080/ms-test-webclient/delay")
.headers(httpHeaders -> httpHeaders.set("Content-Type", "application/json"))
.retrieve()
.toEntity(String.class)
.flatMap(Mono::just)
.timeout(Duration.ofSeconds(20))
.onErrorResume(TimeoutException.class, ex -> {
String message = "Webclient timeout";
return Mono.error(new TimeoutException(message).initCause(ex));
});
}
@GetMapping("test")
public Mono<?> test() {
return call();
}
@GetMapping("delay")
@SneakyThrows
public String delayresponse() {
Thread.sleep(15000);
return "success";
}
}
it should return 200 instead of 500 and webclient timeout exception.