ars*_*nal 2 java performance multithreading executorservice resttemplate
我不是多线程专家,但我看到我当前使用的代码存在一些性能问题ExecutorService.
我正在开发一个项目,在这个项目中,我需要对我的服务器进行HTTP URL调用,如果响应时间过长则会超时.目前它正在返回简单的JSON字符串..
我目前的要求是10 ms.在10 ms其中应该能够从服务器获取数据.我猜它是可能的,因为它只是对同一数据中心内的服务器的HTTP调用.
我的客户端程序和实际服务器在同一个数据中心内,并且ping时间延迟0.5 ms在它们之间,所以它应该是可行的.
我用RestTemplate它来进行URL调用.
下面是我为我写的代码,使用ExecutorService和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(100, 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;
}
}
Run Code Online (Sandbox Code Playgroud)
下面是我的Task类,它实现了Callable接口 -
class Task implements Callable<String> {
private RestTemplate restTemplate = new RestTemplate();
public String call() throws Exception {
// TimerTest timer = TimerTest.getInstance(); // line 3
String response = restTemplate.getForObject(url, String.class);
// timer.getDuration(); // line 4
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我在另一个类代码DemoTest它调用getData的方法URLTest类500 times,并测量第95百分位的是端到端的-
public class DemoTest {
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(); // line 1
bc.getData();
timer.getDuration(); // line 2
}
// this method prints out the 95th percentile
logPercentileInfo();
}
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,我总是看到第95百分位数14-15 ms(这对我的用例来说是不好的,因为它是端到端流程,这就是我需要测量的).
我很惊讶为什么?正在ExectuorFramework这里将所有的延迟?可能是每个任务都已提交,并且提交线程正在等待(通过future.get),直到任务完成为止.
我的主要目标是尽可能减少延迟.我的用例很简单,在启用了TIMEOUT功能的情况下对我的某个服务器进行URL调用,这意味着如果服务器花了很多时间来响应,那么Timeout整个电话.客户将从那里可以多线程的应用程序调用我们的代码.
有什么我缺少的或ExecutorService我需要使用的其他一些口味?我怎样才能提高我的表现?任何建议都会有很大的帮助..
任何一个例子将非常感激..我正在阅读ExecutorCompletionService不确定我是否应该使用这个或其他东西..
至于你的观察,你在外面测量15毫秒,但内部只测量3毫秒,我的赌注是建造带来RestTemplate差异.这可以通过重构来解决.
请注意,它RestTemplate是一个重量级,线程安全的对象,旨在部署为应用程序范围的单例.您当前的代码严重违反了此意图.
如果您需要异步HTTP请求,您应该使用AsyncHttpClient基于下面的Netty 的异步HTTP库,它再次基于Java NIO.这意味着您不需要为每个未完成的HTTP请求占用一个线程.AsyncHttpClient也适用于Futures,所以你将拥有一个习惯的API.它也可以与回调一起使用,这是异步方法的首选.
但是,即使您保留当前的同步库,也应该至少在REST客户端上配置超时,而不是让它运行.
| 归档时间: |
|
| 查看次数: |
2388 次 |
| 最近记录: |