使 REST 客户端调用更快的技巧
Tips on making REST client calls faster
我一直在尝试使用 Spring 的 RestTemplate
和 Java 的 URLConnection
对外部 API 进行 REST 客户端调用.我很沮丧,循环 100 次执行相同的 REST GET 调用(returns 一个小的 JSON 响应)需要大约 60 秒 RestTemplate
和大约 53 秒 URLConnection
.我正在测试这个,因为我的网络应用程序需要通过 HTTP GET、PUT 和 POST 对这个外部 API 进行相当多的调用,所以我试图编写这些调用以尽可能高效.
我可以做些什么来提高下面任一代码片段的效率吗?或者是否有另一个库作为 REST 客户端被认为是高效的?我想使用 RestTemplate
,但如果这意味着更快的客户端 REST 调用,我也可以通过 URLConnection
进入更低级别。
也许这是我的一个错误假设,但我认为对端点进行 100 次 HTTP GET 调用,returns 一个小的 JSON 响应不会超过 10 秒。
以下是我一直在试验的方法(credsProvider
、requestFactory
和 restTemplate
是在方法之外初始化的,认为 "new'ing" 这些重复可能会导致性能问题)
public static String performGetRestRequest(String host, int port, String user, String pass, String endPoint) throws Exception {
credsProvider.setCredentials(
new AuthScope(host, port),
new UsernamePasswordCredentials(user, pass));
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
requestFactory.setHttpClient(httpclient);
return restTemplate.getForObject("http://" + host + ":" + port + endPoint, String.class);
}
public static String performGetRestRequestWithPureJava(String host, int port, String endPoint) throws Exception {
URLConnection connection = new URL("http://" + host + ":" + port + endPoint).openConnection();
connection.setRequestProperty("Accept-Charset", CHARSET);
connection.setRequestProperty("Accept", "application/json");
String inputLine;
StringBuilder sb = new StringBuilder();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), CHARSET));
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
in.close();
return sb.toString();
}
使用 ASyncTask 和 URLConnection 显然比使用现有的其他库要慢。考虑使用 Volley 或 Retrofit。
看看 this 文章。
在开始优化客户端之前,您应该确保时间确实花在了那里。首先,您需要测量服务器响应请求所花费的时间。您的网络往返时间是多少?这将使您更全面地了解时间的去向。
我无法评论 Spring 的 REST 模板,因为我从未使用过它。但是从 URLConnection::getInputStream()
返回的流中读取将阻塞,直到服务器端实际发送数据。因此,对 performGetRestRequestWithPureJava(..)
调用的测量 "client time" 包括网络往返以及服务器响应请求所花费的时间。
附注:如果您向同一目的地发出重复请求,请不要重复创建新的 URLConnection 实例并调用 openConnection()
。而是在连接已打开的情况下重新使用单个实例。
使用下面的库。它更快更容易使用
<dependency>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client</artifactId>
</dependency>.
我一直在尝试使用 Spring 的 RestTemplate
和 Java 的 URLConnection
对外部 API 进行 REST 客户端调用.我很沮丧,循环 100 次执行相同的 REST GET 调用(returns 一个小的 JSON 响应)需要大约 60 秒 RestTemplate
和大约 53 秒 URLConnection
.我正在测试这个,因为我的网络应用程序需要通过 HTTP GET、PUT 和 POST 对这个外部 API 进行相当多的调用,所以我试图编写这些调用以尽可能高效.
我可以做些什么来提高下面任一代码片段的效率吗?或者是否有另一个库作为 REST 客户端被认为是高效的?我想使用 RestTemplate
,但如果这意味着更快的客户端 REST 调用,我也可以通过 URLConnection
进入更低级别。
也许这是我的一个错误假设,但我认为对端点进行 100 次 HTTP GET 调用,returns 一个小的 JSON 响应不会超过 10 秒。
以下是我一直在试验的方法(credsProvider
、requestFactory
和 restTemplate
是在方法之外初始化的,认为 "new'ing" 这些重复可能会导致性能问题)
public static String performGetRestRequest(String host, int port, String user, String pass, String endPoint) throws Exception {
credsProvider.setCredentials(
new AuthScope(host, port),
new UsernamePasswordCredentials(user, pass));
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
requestFactory.setHttpClient(httpclient);
return restTemplate.getForObject("http://" + host + ":" + port + endPoint, String.class);
}
public static String performGetRestRequestWithPureJava(String host, int port, String endPoint) throws Exception {
URLConnection connection = new URL("http://" + host + ":" + port + endPoint).openConnection();
connection.setRequestProperty("Accept-Charset", CHARSET);
connection.setRequestProperty("Accept", "application/json");
String inputLine;
StringBuilder sb = new StringBuilder();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), CHARSET));
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
in.close();
return sb.toString();
}
使用 ASyncTask 和 URLConnection 显然比使用现有的其他库要慢。考虑使用 Volley 或 Retrofit。
看看 this 文章。
在开始优化客户端之前,您应该确保时间确实花在了那里。首先,您需要测量服务器响应请求所花费的时间。您的网络往返时间是多少?这将使您更全面地了解时间的去向。
我无法评论 Spring 的 REST 模板,因为我从未使用过它。但是从 URLConnection::getInputStream()
返回的流中读取将阻塞,直到服务器端实际发送数据。因此,对 performGetRestRequestWithPureJava(..)
调用的测量 "client time" 包括网络往返以及服务器响应请求所花费的时间。
附注:如果您向同一目的地发出重复请求,请不要重复创建新的 URLConnection 实例并调用 openConnection()
。而是在连接已打开的情况下重新使用单个实例。
使用下面的库。它更快更容易使用
<dependency>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client</artifactId>
</dependency>.