在 asyncio.run 外面建好 ClientSession,第二次调用 asyncio.run 时所有请求都报 RuntimeError: Session is closed,连接池跟着旧循环一起关了,第一次跑却是好的,重试也一样。日志里能对上时间点,这种反而好排。
ClientSession 绑定创建它时的那个事件循环,run 结束循环就关闭,连接池里的连接随之失效,复用之前不检查状态,再发请求自然报已关闭。这一点先确认清楚,后面就不用反复试。
async def main():
async with aiohttp.ClientSession() as s:
await fetch_all(s)
asyncio.run(main())
「aiohttp 会话跨循环」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。
报错里带路径的,先去看那个路径在不在、权限对不对。
处理上按这个顺序:session 在协程内部创建,跟着当次循环的生命周期走,不要提到外面;需要复用的把 run 只调用一次,业务都在同一个循环里跑;框架里用启动钩子建 session,关闭钩子里释放,别在请求处理函数里临时创建。
结果对不对很好判断,连续调用两次 run 都能正常返回,不再出现 Session is closed,连接池的状态也恢复正常。
