python发送异步请求
在 Python 中,使用asyncio异步框架可以实现异步任务的调度和执行,选择使用httpx来发送异步的请求。异步和同步请求方式的对比:
# 异步请求
async def async_send_request():
async with httpx.AsyncClient() as client:
response = await client.request("GET", url)
return response.text
async def async_main():
start_time = time.time()
tasks = [async_send_request() for i in range(100)]
results = await asyncio.gather(*tasks)
end_time = time.time()
print(f"程序耗时:{int((end_time - start_time) * 1000)}")
# 同步请求
def send_request():
with httpx.Client() as client:
response = client.request("GET", url)
return response.text
def main():
start_time = time.time()
results = [send_request() for i in range(100)]
end_time = time.time()
print(f"程序耗时:{int((end_time - start_time) * 1000)}")
异步和同步请求耗时的对比:
if __name__ == '__main__':
asyncio.run(async_main())
main()
程序耗时:1161
程序耗时:10558
java发送异步请求
Java异步可以通过多种方式实现,这里选择CompletableFuture异步框架,请求方式使用HttpClient。也可以使用HttpAsyncClient发送异步请求,需传入FutureCallback接口实现类参数来进行异步的回调,请求返回的是一个Future对象。异步请求的实现如下:
// 同步发送请求
public static void run() throws IOException {
long startTime = System.currentTimeMillis();
CloseableHttpClient httpclient = HttpClients.createDefault();
for (int i = 0; i < 10; i++) {
try {
sendRequest(url, httpclient);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
long endTime = System.currentTimeMillis();
System.out.println("程序耗时:" + (endTime - startTime));
httpclient.close();
}
// 异步发送请求
public static void runAsync() throws IOException {
long startTime = System.currentTimeMillis();
CloseableHttpClient httpclient = HttpClients.createDefault();
List<CompletableFuture<String>> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
return sendRequest(url, httpclient);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
futures.add(future);
}
CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
allOf.join(); // 等待所有异步操作完成
long endTime = System.currentTimeMillis();
System.out.println("程序耗时:" + (endTime - startTime));
httpclient.close();
}
// 使用HttpAsyncClient方式,异步发送请求
public static void runAsyncClient() throws IOException, InterruptedException {
long startTime = System.currentTimeMillis();
CloseableHttpAsyncClient httpAsyncClient = HttpAsyncClients.custom().build();
httpAsyncClient.start();
HttpGet request = new HttpGet(url);
MyCallback myCallback = new MyCallback();
for (int i = 0; i < 10; i++) {
httpAsyncClient.execute(request, myCallback);
}
Thread.sleep(1500); // 等待所有异步操作完成
long endTime = myCallback.responseTime;
System.out.println("程序耗时:" + (endTime - startTime));
httpAsyncClient.close();
}
public static String sendRequest(String url, CloseableHttpClient httpclient) throws IOException {
HttpGet request = new HttpGet(url);
HttpResponse response = httpclient.execute(request);
return EntityUtils.toString(response.getEntity()) ;
}
private static final class MyCallback implements FutureCallback<HttpResponse> {
public long responseTime;
@Override
public void completed(HttpResponse httpResponse) {
responseTime = Math.max(System.currentTimeMillis(), responseTime);
}
@Override
public void failed(Exception e) {
e.printStackTrace();
}
@Override
public void cancelled() {
}
}
异步和同步发送请求的对比:
public static void main(String[] args) throws IOException, InterruptedException {
runAsync();
run();
runAsyncClient();
}
程序耗时:1253
程序耗时:7486
程序耗时:1053
总结
当程序需要多频次地访问请求时,可以使用异步请求的方式解决网络IO造成的阻塞等待,使程序达到最佳地执行效率。