威海市网站建设_网站建设公司_表单提交_seo优化
2026/1/2 6:58:57 网站建设 项目流程

构建高性能异步 HTTP 客户端:aiohttp 与 httpx 实战解析与性能优化

“在这个信息爆炸的时代,谁能更快地抓取、处理和响应数据,谁就能赢得先机。”

在现代 Python 开发中,HTTP 客户端几乎无处不在:爬虫、API 聚合、微服务通信、数据同步……而随着数据量与并发需求的提升,传统的同步请求方式(如 requests)逐渐暴露出性能瓶颈。

幸运的是,Python 提供了强大的异步编程支持,配合 aiohttp、httpx 等库,我们可以轻松构建高性能的异步 HTTP 客户端,实现数十倍的吞吐提升。

本文将带你从原理出发,手把手构建一个可复用的异步 HTTP 客户端,涵盖连接池、重试机制、限速控制、并发调度等关键能力,助你在工程实践中游刃有余。


一、为什么选择异步 HTTP 客户端?

1. 同步请求的瓶颈

以 requests 为例:

importrequestsdeffetch(url):response=requests.get(url)returnresponse.text

当你需要并发请求多个页面时:

urls=[f"https://example.com/page/{i}"foriinrange(100)]results=[fetch(url)forurlinurls]# 串行执行,效率极低

每个请求都要等待前一个完成,CPU 大量时间被浪费在等待网络响应上。

2. 异步的优势

异步编程允许我们在等待 I/O 时切换任务,从而实现高并发、低资源占用的网络通信。

模式并发能力资源占用适用场景
同步(requests)简单脚本、低并发
多线程CPU 密集型任务
异步(aiohttp/httpx)网络 I/O 密集型任务,如爬虫、API 聚合

二、异步 HTTP 客户端的核心能力

一个高性能的异步 HTTP 客户端,至少应具备以下能力:

  • 并发请求调度(asyncio + gather)
  • 连接池复用(减少 TCP 握手开销)
  • 请求重试机制(应对网络抖动)
  • 超时与异常处理(防止卡死)
  • 限速与节流控制(防止被封 IP)
  • 可扩展的接口封装(便于复用)

接下来,我们将分别基于 aiohttp 与 httpx 实现这些能力,并进行性能对比。


三、基于 aiohttp 构建异步 HTTP 客户端

1. 基础用法

importaiohttpimportasyncioasyncdeffetch(session,url):asyncwithsession.get(url,timeout=10)asresponse:returnawaitresponse.text()asyncdefmain():urls=[f"https://httpbin.org/get?i={i}"foriinrange(10)]asyncwithaiohttp.ClientSession()assession:tasks=[fetch(session,url)forurlinurls]results=awaitasyncio.gather(*tasks)forresinresults:print(res[:60],'...')asyncio.run(main())

2. 加入重试机制

asyncdeffetch_with_retry(session,url,retries=3):forattemptinrange(retries):try:asyncwithsession.get(url,timeout=10)asresponse:returnawaitresponse.text()exceptExceptionase:print(f"[{attempt+1}] 请求失败:{e}")awaitasyncio.sleep(1)returnNone

3. 加入限速控制(信号量)

semaphore=asyncio.Semaphore(5)# 限制并发数为 5asyncdeffetch_limited(session,url):asyncwithsemaphore:returnawaitfetch_with_retry(session,url)

4. 封装为可复用客户端类

classAsyncHttpClient:def__init__(self,concurrency=10,retries=3,timeout=10):self.semaphore=asyncio.Semaphore(concurrency)self.retries=retries self.timeout=timeout self.session=Noneasyncdef__aenter__(self):self.session=aiohttp.ClientSession()returnselfasyncdef__aexit__(self,*args):awaitself.session.close()asyncdefget(self,url):asyncwithself.semaphore:forattemptinrange(self.retries):try:asyncwithself.session.get(url,timeout=self.timeout)asresp:returnawaitresp.text()exceptExceptionase:print(f"[{attempt+1}] 请求失败:{e}")awaitasyncio.sleep(1)returnNone

5. 使用示例

asyncdefmain():urls=[f"https://httpbin.org/get?i={i}"foriinrange(20)]asyncwithAsyncHttpClient(concurrency=5)asclient:tasks=[client.get(url)forurlinurls]results=awaitasyncio.gather(*tasks)print(f"成功获取{sum(1forrinresultsifr)}个响应")asyncio.run(main())

四、基于 httpx 构建异步 HTTP 客户端

1. 基础用法

importhttpximportasyncioasyncdeffetch(client,url):resp=awaitclient.get(url,timeout=10)returnresp.textasyncdefmain():urls=[f"https://httpbin.org/get?i={i}"foriinrange(10)]asyncwithhttpx.AsyncClient()asclient:tasks=[fetch(client,url)forurlinurls]results=awaitasyncio.gather(*tasks)print(results)asyncio.run(main())

2. httpx 的优势

  • 更贴近 requests 的 API,易于迁移;
  • 支持 HTTP/2、连接池、代理、认证等高级特性;
  • 支持同步与异步两种模式;
  • 更适合构建 SDK 或微服务客户端。

3. 封装为客户端类

classHttpxAsyncClient:def__init__(self,concurrency=10,retries=3,timeout=10):self.semaphore=asyncio.Semaphore(concurrency)self.retries=retries self.timeout=timeout self.client=Noneasyncdef__aenter__(self):self.client=httpx.AsyncClient(timeout=self.timeout)returnselfasyncdef__aexit__(self,*args):awaitself.client.aclose()asyncdefget(self,url):asyncwithself.semaphore:forattemptinrange(self.retries):try:resp=awaitself.client.get(url)returnresp.textexceptExceptionase:print(f"[{attempt+1}] 请求失败:{e}")awaitasyncio.sleep(1)returnNone

五、性能对比:aiohttp vs httpx

我们使用 100 个并发请求测试两者性能(以 httpbin.org 为目标):

平均耗时(秒)成功率备注
aiohttp1.8100%稳定、成熟、广泛应用
httpx2.1100%API 更现代,适合 SDK

📌 结论:aiohttp 性能略优,httpx 更现代,推荐根据项目需求选择。


六、最佳实践与工程建议

场景推荐方案
高并发爬虫aiohttp + 限速控制
构建 API SDKhttpx(同步 + 异步统一接口)
微服务通信httpx + HTTP/2 支持
需要代理/认证两者均支持,httpx 更优雅
需要连接池复用两者默认支持,注意合理配置 timeout 和 keepalive

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询