Aiohttp异步请求报错ClientConnectionError: Connector is closed如何解决
问题原因
- 核心触发点:你所有
ClientSession共享同一个全局TCPConnector实例,而ClientSession执行close()方法时,默认会同步关闭绑定的connector。第一个请求执行完成后调用await session.close(),直接把全局connector销毁,后续请求复用已经关闭的connector就会抛出aiohttp.client_exceptions.ClientConnectionError: Connector is closed.异常。 - 补充说明:你设置
limit=1只是限制TCP连接的并发数为1,本身不会触发报错,仅会让请求串行执行,是错误的session关闭逻辑导致的问题。
修复方案
方案1:复用ClientSession(官方推荐)
aiohttp官方建议整个应用生命周期尽量复用同一个ClientSession,避免重复创建销毁的开销,也能从根源避免connector共享的问题。修复后代码如下:
import aiohttp import asyncio async def get(session, url): print('started request', url) response = await session.get(url, timeout=5) print(await response.text()) async def main(): connector = aiohttp.TCPConnector(limit=1) # 全局仅创建一个ClientSession,用上下文管理器自动管理生命周期 async with aiohttp.ClientSession(connector=connector) as session: tasks = [ asyncio.create_task(get(session, 'http://httpbin.org/ip')), asyncio.create_task(get(session, 'http://httpbin.org/ip')), asyncio.create_task(get(session, 'http://httpbin.org/ip')), asyncio.create_task(get(session, 'http://httpbin.org/ip')), asyncio.create_task(get(session, 'http://httpbin.org/ip')), asyncio.create_task(get(session, 'http://httpbin.org/ip')), ] await asyncio.wait(tasks) if __name__ == "__main__": asyncio.run(main())
该方案通过async with上下文管理session,会自动处理session和connector的关闭逻辑,不需要手动调用close()方法,代码更简洁也更安全。
方案2:保留多Session逻辑,设置connector_owner=False
如果你确实需要每个请求单独创建ClientSession,在初始化Session时指定connector_owner=False,即可让Session关闭时不销毁绑定的共享connector,仅需要修改get函数中session创建的代码行即可:
session = aiohttp.ClientSession(connector=connector, connector_owner=False)
内容的提问来源于stack exchange,提问作者yesterdaycode
相关产品推荐
相关产品推荐

