Java 如何在RequestFactory中有效地使用RestTemplate?
我正在从事一个项目,在这个项目中,我需要对运行Restful服务的服务器进行HTTP URL调用,该服务将响应作为JSON字符串返回。我在这里使用Java 如何在RequestFactory中有效地使用RestTemplate?,java,multithreading,performance,resttemplate,Java,Multithreading,Performance,Resttemplate,我正在从事一个项目,在这个项目中,我需要对运行Restful服务的服务器进行HTTP URL调用,该服务将响应作为JSON字符串返回。我在这里使用restemplate和httpcomponents客户端httprequestfactory来执行url 我使用httpcomponents客户端httprequestfactory在我的restemplate上设置了http请求超时(读取和连接超时) 以下是我的界面: public interface Client { // for sy
restemplate
和httpcomponents客户端httprequestfactory
来执行url
我使用httpcomponents客户端httprequestfactory
在我的restemplate
上设置了http请求超时(读取和连接超时)
以下是我的界面:
public interface Client {
// for synchronous
public String getSyncData(String key, long timeout);
// for asynchronous
public String getAsyncData(String key, long timeout);
}
下面是我的客户端接口的实现-
public class DataClient implements Client {
private final RestTemplate restTemplate = new RestTemplate();
private ExecutorService executor = Executors.newFixedThreadPool(10);
// for synchronous call
@Override
public String getSyncData(String key, long timeout) {
String response = null;
try {
Task task = new Task(key, restTemplate, timeout);
// direct call, implementing sync call as async + waiting is bad idea.
// It is meaningless and consumes one thread from the thread pool per a call.
response = task.call();
} catch (Exception ex) {
PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
}
return response;
}
// for asynchronous call
@Override
public Future<String> getAsyncData(String key, long timeout) {
Future<String> future = null;
try {
Task task = new Task(key, restTemplate, timeout);
future = executor.submit(task);
} catch (Exception ex) {
PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
}
return future;
}
}
据我所知,您重复使用相同的
restemplate
对象,但每个任务都执行这一行:restemplate.setRequestFactory(clienthtprequestfactory())代码>。这似乎有竞争条件,例如一个任务
可以设置另一个任务
将意外使用的请求工厂
否则,您似乎正确地使用了restemplate
你的超时多长时间改变一次?如果主要使用一个或两个超时,则可以使用带有预加载超时的RequestFactory
构造函数创建一个或两个restemplate
s。如果你是一个追求效率的人,那么创建一个HashMap
,它在每次请求新超时时缓存一个带有特定超时的restemplate
否则,查看和的代码,它们看起来并不特别繁重,因此反复调用它们可能不会造成太大的瓶颈。FYI有一个AsyncRestTemplate spring 4。@AdamGent我明白了,它在我的场景中有用吗?AsyncRestTemplate可能完全消除对任务的需求,当它返回一个未来时
。您可以选择在普通RestTemplate或异步RestTemplate上运行请求,而不是在直接执行任务或将任务提交给执行者之间进行选择。如何避免这种竞争条件?每个客户都将在其代码库中使用此库,因此他们将始终只设置一个超时,不会不断更改每次调用的超时值。一旦设置好,它将用于他们对该库的所有调用。修复竞争条件的简单方法是在创建任务之前创建一个新的RestTemplate。那么您根本不需要将超时传递给任务。如果一个库使用只有一个超时设置,我建议添加DataClient.setTimeout(int timeout)。然后,您可以使用一个RestTemplate,通过该函数设置一次超时,然后继续使用life。您能提供一个示例吗?这将帮助我更好地理解。哪一个例子?为了避免竞争条件,将“clientHttpRequestFactory”从任务移动到DataClient。然后任务创建行看起来就像“任务任务=新任务(键,新RestTemplate(clientHttpRequestFactory(超时))
class Task implements Callable<String> {
private RestTemplate restTemplate;
private String key;
private long timeout; // in milliseconds
public Task(String key, RestTemplate restTemplate, long timeout) {
this.key = key;
this.restTemplate = restTemplate;
this.timeout = timeout;
}
public String call() throws Exception {
String url = "some_url_created_by_using_key";
// does this looks right the way I am setting request factory?
// or is there any other effficient way to do this?
restTemplate.setRequestFactory(clientHttpRequestFactory());
String response = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
return response;
}
private static ClientHttpRequestFactory clientHttpRequestFactory() {
// is it ok to create a new instance of HttpComponentsClientHttpRequestFactory everytime?
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(timeout); // setting timeout as read timeout
factory.setConnectTimeout(timeout); // setting timeout as connect timeout
return factory;
}
}
String response = DataClientFactory.getInstance().getSyncData(keyData, 100);