We are using WebClient to communicate with another service. For the time being (in performance testing) its a mock which returns response after 150 ms.
But in the service, time taken by WebClient is far greater than this. We had set timeout at 250 ms, and in that case we found that less than 1% request where getting timed out. We increased the timeout to check the max time taken by WebClient. In this case we found that latency goes upto 500-600 ms for some requests.
Both the service and mock is in AWS, so there is minimal network latency. We verified it via New Relic too. Our service was getting response in average of about 153 ms.
So the question why WebClient is taking this extra time for some requests. Is this some configuration issue at our end or a known problem in WebClient. How can we solve this?
We are using Spring Boot version 2.2.0.RELEASE with web flux, netty etc being on default versions that are bundled with this spring boot version.
Code that we are using to create WebClient and sending requests:
WebClient webClient;
@PostConstruct
public void init() {
webClient = WebClient.create();
}
public Mono<?> postRequest(final RequestContext requestContext,
final MultiValueMap headers, final MediaType contentType, final MediaType acceptType) {
Mono<?> response;
try {
String url = requestContext.getDownStreamObject().getDownstreamRequestUrl();
URI uri = new URI(url);
long webClientstartTime = System.currentTimeMillis();
response = webClient.post().uri(uri)
.contentType(contentType)
.headers(httpHeaders -> {
if (Objects.nonNull(headers)) {
httpHeaders.addAll(headers);
}
})
.bodyValue(requestContext.getRequest())
.accept(acceptType)
.exchange()
.timeout(Duration.ofMillis(requestContext.getDownStreamObject().getTimeout()))
.doOnSuccess(clientResponse -> log.info("clientResponse.statusCode() : {}, {} , requestId : {}, host : {} ,webClient latency : {}",
clientResponse.statusCode(), clientResponse.toString(),requestContext.getRequestId(), uri.getHost(),
System.currentTimeMillis() - webClientstartTime))
.doOnError(throwable -> {
log.error("clientResponse error :{} , requestId :{}, sessionId: {}, host : {}, webclient latency : {}",
throwable,requestContext.getRequestId(), requestContext.getServiceId(), uri.getHost(), System.currentTimeMillis() - webClientstartTime);
})
.flatMap(clientResponse -> clientResponse.bodyToMono(String.class));
return response;
} catch (Exception ex) {
log.error("Some exception while processing post request for requestId :{}, sessionId: {}. Error: {}",
requestContext.getRequestId(), requestContext.getServiceId(), Utility.exceptionFormatter(ex));
}
return null;
}