I am working on a project in which I am trying to make a URL call to one of my server using RestTemplate
which gives me back a JSON String as a response and it is working fine...
Now I decided to do some performance testing on that...
Below is my code which uses ExecutorService
and Callables
-
public class URLTest {
private ExecutorService executor = Executors.newFixedThreadPool(10);
public String getData() {
Future<String> future = executor.submit(new Task());
String response = null;
try {
System.out.println("Started..");
response = future.get(200, TimeUnit.MILLISECONDS);
System.out.println("Finished!");
} catch (TimeoutException e) {
System.out.println("Terminated!");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return response;
}
}
Below is my Task class which implements Callable interface -
class Task implements Callable<String> {
private RestTemplate restTemplate = new RestTemplate();
public String call() throws Exception {
String url = "some_url";
// TimerTest timer = TimerTest.getInstance(); // line 3
String response = restTemplate.getForObject(url, String.class);
// timer.getDuration(); // line 4
System.out.println(response);
return response;
}
}
And below is my code in another class DemoTest
which calls the getData
method in URLTest
class 500 times
and measure the 95th percentile of it as that's what I need to do -
public class DemoTest {
public static void main(String[] args) {
URLTest bc = new URLTest();
for (int i = 0; i <= 500; i++) {
TimerTest timer = TimerTest.getInstance(); // line 1
bc.getData();
timer.getDuration(); // line 2
}
// this method prints out the 95th percentile
logPercentileInfo();
}
}
With the above code as it is, I always see as 95th percentile as 14-15 ms
(which is bad for my use case as it is end to end flow and that's what I need to measure) but if I comment out line 1
and line 2
in DemoTest
class and uncomment line 3
and line 4
in Task
class and then run the program again it will start giving me 95th percentile as 3 ms
.
I am surprised why? Is ExectuorFramework
adding all the latency here? And why if I just measure the performance of RestTemplate
call, then it always gives me better performance as compared to end to end performance?
My main goal is to reduce the latency here as much as possible.. My use case is simple, Make a URL call to one of my server with a TIMEOUT feature enabled, meaning if the server is taking lot of time to response, then Timeout the whole call.
Both my client program and server are running in PRODUCTION in the same datacenter so ping time is 0.5 ms around..
I ran couple of times to do this test and still the same result..
Is there anything I am missing or some other flavors of ExecutorService
I need to use? How can I improve my performance here? Any suggestions will be of great help..
UPDATE:-
Added some warmup time -
public static void main(String[] args) {
URLTest bc = new URLTest();
// little bit warmup
for (int i = 0; i <= 500; i++) {
bc.getData();
}
for (int i = 0; i <= 500; i++) {
TimerTest timer = TimerTest.getInstance();
bc.getData();
timer.getDuration();
}
logPercentileInfo();
}