aiohttp连接池大小由tcpconnector控制,而非clientsession;默认limit=100(全局)、limit_per_host=100(单域名),需显式传入connector配置,且不可运行时修改。

asyncio + aiohttp 连接池大小由谁控制?
连接池大小不归 aiohttp.ClientSession 自己决定,而是由底层的 aiohttp.TCPConnector 管理。默认情况下,它只允许最多 100 个并发连接(limit=100),且对单个 host 限制 100 个(limit_per_host=100)。如果你没显式传入 connector,就用的是这个默认值。
常见错误现象:ClientOSError: Cannot connect to host 或请求明显卡在某处不动——很可能是连接池被占满,新请求在排队等空闲连接。
- 必须通过
connector=aiohttp.TCPConnector(...)显式构造并传给ClientSession -
limit控制全局总连接数,limit_per_host控制每个域名最多多少连接;两者都需按实际目标站点数量和并发策略设值 - 设太小会瓶颈,设太大可能触发目标站限流或本地端口耗尽(尤其 Windows 上 ephemeral port 不足)
如何在运行时安全地调整连接池大小?
aiohttp.TCPConnector 实例一旦绑定到 ClientSession,其 limit 和 limit_per_host 就不可变——没有类似 set_limit() 的方法。所谓“动态”,只能靠重建连接器+会话来实现,但必须确保旧会话已彻底关闭。
使用场景:爬取过程中发现响应延迟突增,怀疑是连接池过载;或根据目标站点返回的 Retry-After / X-RateLimit-Remaining 头自动降级并发度。
- 不能直接改
session.connector.limit,那只是只读属性,改了也没用 - 需先调用
await session.close(),再创建新TCPConnector和新ClientSession - 如果多个协程共用一个 session,重建前必须协调停用所有正在使用的请求,否则会抛
RuntimeError: Session is closed - 建议把 session 封装成可热替换的管理器,用
async with包裹关键请求段,避免长期持有 session
有没有更轻量的“伪动态”方案?
不重建 session,也能在一定程度上缓解连接争抢——靠控制发起请求的协程并发数,而非底层连接池本身。这其实是更常用、更可控的做法。
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
性能影响:连接池大小应 ≥ 并发请求数,否则协程会在 connector 内部排队,看似“并发”实则串行等待连接。
- 用
asyncio.Semaphore(n)限制同时发起的请求数,比如sem = asyncio.Semaphore(50) - 每个请求前
async with sem:,这样即使连接池 limit=100,实际也只让 50 个请求同时尝试获取连接 - 配合
limit_per_host=30可防止单站被打爆,比全局调大 pool 更安全 - 这种方案无需重建 session,也不影响连接复用率,推荐作为第一层流量调控
为什么不用 asyncio.Pool 或自定义连接池?
aiohttp 的 TCPConnector 已经是经过压测的异步连接池实现,它处理 DNS 缓存、SSL 会话复用、空闲连接回收、超时熔断等细节。自己用 asyncio.Queue 套 aiohttp.ClientSession 反而容易出问题。
容易踩的坑:
- 手动维护 session 列表 + queue 分发,会导致连接无法复用(每个 session 有独立 connector)
- 忽略 connector 的
keepalive_timeout,导致大量 TIME_WAIT 连接堆积 - 误以为增大
limit就能线性提升吞吐,实际受 DNS 解析、SSL 握手、目标响应速度制约更大
真正需要关注的不是“池子多大”,而是连接是否及时释放、是否被复用、以及请求节奏是否匹配目标服务能力。连接池参数只是其中一环,调得太激进反而让问题更隐蔽。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










