如何在 java 中高效地进行多次 API 调用
How to make multiple API calls in a efficient way in java
我有一个 10 万用户的列表。我必须遍历列表并对服务器进行 API 调用以获取结果。每次我创建一个新的 URL 连接并进行 APi 调用,然后在我读取输入流后关闭连接,但它花费了太多时间。
有没有优化的方法,比如多次使用 URL 连接的同一个实例而不是关闭它?还是换个第三方库会提高执行速度?
我在循环中调用以下方法来获取输出。
private String getOutput(String loginName) {
String responseStatus = null;
HttpURLConnection connection = null;
try {
URL url= new URL(<<https://api.junk.123.com/output>>);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("apikey", "authentication key");
connection.setUseCaches(false);
connection.setDoOutput(true);
//Send request
try(DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())){
JsonObject jsonParam = new JsonObject();
jsonParam.putString("loginName", "loginName");
outputStream.writeBytes(jsonParam.toString());
outputStream.flush();
}
//Get response
InputStream inputStream;
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK){
inputStream = connection.getInputStream();
} else {
inputStream = connection.getErrorStream();
}
if(null == inputStream){
return String.valueOf(connection.getResponseCode());
}
StringBuilder response = new StringBuilder();
try (BufferedReader inputBuffer = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while (null != (line = inputBuffer.readLine())) {
response.append(line);
response.append("\r");
}
}
JsonObject jsonObject = new JsonObject(response.toString());
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
responseStatus = "success";
} else {
responseStatus = String.valueOf(connection.getResponseCode()) + jsonObject.getString("errorMessage") ;
}
} catch (MalformedURLException e) {
logger.error("Malformed URL exception occurred while calling the API", entry.getKey(), e);
} catch (IOException e) {
logger.error("Creation of connection failed while calling the API", entry.getKey(), e);
} catch (Exception e) {
logger.error("Error occurred while calling the API", entry.getKey(), e);
} finally {
if (null != connection){
connection.disconnect();
}
}
return responseStatus;
}
此问答解释了 HTTP 持久连接是由 HttpURLConnection 在幕后实现的:
但是,这可能还不够。如果您使用单个客户端线程进行抓取,您将受到请求的 往返时间 的限制;也就是说,在第一个请求的结果返回给您之前,您不能开始第二个请求。您可以通过使用多个客户端线程在一定程度上补救此问题。
然而 (#2) 并行发送多个请求也有其局限性。超过某个点,您将使客户端、服务器或网络饱和。此外,某些服务器具有节流机制来限制客户端可以发出的请求数。
获得最大吞吐量的方法是重新设计 API 以便单个请求可以获得多个用户的信息。
我有一个 10 万用户的列表。我必须遍历列表并对服务器进行 API 调用以获取结果。每次我创建一个新的 URL 连接并进行 APi 调用,然后在我读取输入流后关闭连接,但它花费了太多时间。
有没有优化的方法,比如多次使用 URL 连接的同一个实例而不是关闭它?还是换个第三方库会提高执行速度?
我在循环中调用以下方法来获取输出。
private String getOutput(String loginName) {
String responseStatus = null;
HttpURLConnection connection = null;
try {
URL url= new URL(<<https://api.junk.123.com/output>>);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("apikey", "authentication key");
connection.setUseCaches(false);
connection.setDoOutput(true);
//Send request
try(DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())){
JsonObject jsonParam = new JsonObject();
jsonParam.putString("loginName", "loginName");
outputStream.writeBytes(jsonParam.toString());
outputStream.flush();
}
//Get response
InputStream inputStream;
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK){
inputStream = connection.getInputStream();
} else {
inputStream = connection.getErrorStream();
}
if(null == inputStream){
return String.valueOf(connection.getResponseCode());
}
StringBuilder response = new StringBuilder();
try (BufferedReader inputBuffer = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while (null != (line = inputBuffer.readLine())) {
response.append(line);
response.append("\r");
}
}
JsonObject jsonObject = new JsonObject(response.toString());
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
responseStatus = "success";
} else {
responseStatus = String.valueOf(connection.getResponseCode()) + jsonObject.getString("errorMessage") ;
}
} catch (MalformedURLException e) {
logger.error("Malformed URL exception occurred while calling the API", entry.getKey(), e);
} catch (IOException e) {
logger.error("Creation of connection failed while calling the API", entry.getKey(), e);
} catch (Exception e) {
logger.error("Error occurred while calling the API", entry.getKey(), e);
} finally {
if (null != connection){
connection.disconnect();
}
}
return responseStatus;
}
此问答解释了 HTTP 持久连接是由 HttpURLConnection 在幕后实现的:
但是,这可能还不够。如果您使用单个客户端线程进行抓取,您将受到请求的 往返时间 的限制;也就是说,在第一个请求的结果返回给您之前,您不能开始第二个请求。您可以通过使用多个客户端线程在一定程度上补救此问题。
然而 (#2) 并行发送多个请求也有其局限性。超过某个点,您将使客户端、服务器或网络饱和。此外,某些服务器具有节流机制来限制客户端可以发出的请求数。
获得最大吞吐量的方法是重新设计 API 以便单个请求可以获得多个用户的信息。