I have a REST API service which makes an REST API to an external system using RestTemplate. Time out set is 3 sec.
To make this external call, I have an Executor service fixed thread pool created. Now, in normal testing everything works fine, even the time out set for the internal call. But when I do performance test of my system using jmeter, on one vm, having 4 cores, fixed thread pool size of 50, I start observing the below things.
- Before 30 req / sec throughput, everything works well.
- At 45 req / sec throughput, I observed increased latencies from the internal REST API call. Though the time out set was 3 sec, I observe 5 - 8 sec of latencies from the internal call.
Instant startTime = Instant.now();
ResponseEntity<String> responseEntity = restTemplate
.exchange(url, httpMethod, httpEntity, String.class);
Instant finishTime = Instant.now();
Log.info("Time diff is " + String.valueOf(Duration.between(startTime, finishTime).toMillis()));
- At 45 req / sec throughput, there was a delay at the point when the internal API call is made in a separate thread, looks like the system was waiting for the thread to be available in the pool.
On the 2nd point, wanted to understand how is this possible. Few theories that I have is,
- As external API call is an IO operation, the thread-pool thread executing it goes into "blocked for IO completion" or wait state till it receives the response from external API. And when it receives the response, the thread goes to "ready to run" state, waiting to run, at the mercy of the scheduler. Now, as the traffic was already so high, there were lot other threads already in "ready to run state" & some of these threads, even after receiving the external API response, get the CPU time very late, and that is when the finishTime gets calculated. That means, even if the restTemplate call got the response within 3 sec, executing the Log.info line took time, coz of which the time diff log printed late.
- This theory I don't think is right, but I am just letting out my thoughts. Is it possible that when the thread makes that REST API IO call, and goes in wait state, as the demand for threads from pool is high, the thread is pre-empted from waiting state to cater to another request? and once the response is received from API call, another thread gets assigned to receive that request, assigning of this another thread might have taken time causing the increased latency.
Please let me know if my 1st theory is right, or if not what exactly happens in high throughput cases here that might have been causing more than timeout value latency for the external API call.