【发布时间】:2016-02-26 14:02:19
【问题描述】:
我一直在尝试使用 Spring 的 RestTemplate 和 Java 的 URLConnection 来使 REST 客户端调用外部 API。对于循环 100 次执行相同的 REST GET 调用(返回一个小的 JSON 响应),RestTemplate 大约需要 60 秒,URLConnection 大约需要 53 秒,这让我感到沮丧。我正在对此进行测试,因为我的 Web 应用程序需要通过 HTTP GET、PUT 和 POST 对这个外部 API 进行多次调用,所以我试图编写这些调用以尽可能高效。
我可以做些什么来提高下面任一代码 sn-ps 的效率吗?或者是否有另一个库被认为是高效的 REST 客户端?我想使用RestTemplate,但如果这意味着更快的客户端REST调用,我也可以通过URLConnection进行更底层的操作。
也许这是我的一个错误假设,但我认为对返回一个小的 JSON 响应的端点进行 100 次 HTTP GET 调用不会超过 10 秒。
这是我一直在试验的方法(credsProvider、requestFactory 和 restTemplate 在方法之外被初始化,认为“新”这些重复可能会导致性能问题)
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();
}
【问题讨论】:
-
你有没有测量过服务器端花费了多少时间?
-
restTemplate.getForObject 平均需要大约 600 毫秒,占我在帖子中提到的 61 秒中的 59 秒
-
URLConnection.getInputStream 平均需要大约 540 毫秒,占我提到的 53 秒中的大部分
-
似乎这些调用是瓶颈......我可以用什么替换它们或者我怎样才能让它们更有效率我猜是相关的问题......
-
URLConnection::getInputStream()阻塞,直到服务器端使数据可用。因此,在优化客户端之前,您应该检查在服务器上花费了多少时间以及您的网络往返时间是多少。
标签: java rest resttemplate urlconnection