You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

aiohttp.ClientSession连接缓存超时问题求助:间隔超10秒缓存失效

问题:aiohttp连接缓存失效,间隔超过10秒请求耗时回到首次水平

我想用aiohttp.ClientSession缓存连接来加快请求速度,但发现当用asyncio.sleep模拟的请求间隔超过10秒时,连接会像首次建立一样耗时;间隔小于10秒时则可正常利用缓存。请问该如何解决此问题?

相关代码如下:

import asyncio
import time
import uvloop
import aiohttp

async def main(): 
    conn = aiohttp.TCPConnector(ttl_dns_cache=None,limit_per_host=10) 
    trace_config = aiohttp.TraceConfig() 
    trace_config.on_request_start.append(on_request_start) 
    trace_config.on_request_end.append(on_request_end) 
    session = aiohttp.ClientSession(connector=conn,trace_configs=[trace_config]) 
    await asyncio.create_task(add_task(session,4)) 
    await asyncio.sleep(15) 
    await asyncio.create_task(add_task(session)) 
    await asyncio.create_task(add_task(session)) 
async def on_request_start(session, trace_config_ctx, params): 
    start_time = time.perf_counter() 
    trace_config_ctx.start = start_time 
async def on_request_end(session, trace_config_ctx, params): 
    end_time = time.perf_counter() 
    elapsed = end_time - trace_config_ctx.start 
    print("Request took {}".format(elapsed)) 
async def add_task(session,num=4): 
    task = [] 
    for i in range(num): 
        task.append(fetch('xxxx.com',session)) 
    start_time = time.perf_counter() 
    results = await asyncio.gather(*task) 
    print('=====================') 
async def fetch(url, session):
    # 补充原代码缺失的fetch逻辑
    async with session.get(f'https://{url}') as resp:
        return await resp.text()

if __name__ == '__main__': 
    uvloop.install() 
    asyncio.run(main())

输出结果:

Request took 0.23638559999999997 
Request took 0.24373 
Request took 0.2442225 
Request took 0.2806297999999998 
===================== 
Request took 0.17726310000000112 
Request took 0.18133539999999826 
Request took 0.18915810000000022 
Request took 0.22994100000000017 
===================== 
**USE 'await asyncio.sleep(5)' OR NOT USE IT** 
Request took 0.24224590000000013 
Request took 0.24209349999999996 
Request took 0.24268460000000003 
Request took 0.261196 
===================== 
Request took 0.04700550000000003 
Request took 0.049366400000000255 
Request took 0.05276870000000056 
Request took 0.051986700000000496 
=====================

解决方案

嘿,这个问题我太熟了!核心原因就在你创建TCPConnector时没注意到的默认参数——keepalive_timeout,它的默认值正好是10秒!

也就是说,当连接空闲超过10秒后,aiohttp会自动关闭这个连接,所以你间隔15秒再发请求时,只能重新建立新连接,耗时自然就回到首次请求的水平了。

解决步骤很简单:

在初始化TCPConnector的时候,显式设置一个更大的keepalive_timeout值,比如设置成300秒(5分钟),或者根据你的业务场景调整:

# 修改TCPConnector的创建代码,添加keepalive_timeout参数
conn = aiohttp.TCPConnector(
    ttl_dns_cache=None,
    limit_per_host=10,
    keepalive_timeout=300  # 这里设置为你需要的超时时间,单位秒
)

额外注意事项:

  • 如果你想让连接尽量持久(不推荐盲目设置,最好和服务端配置匹配),可以把keepalive_timeout设为None,但要确认目标服务端是否允许长期保持空闲连接——很多服务端自身也会设置连接超时,比如Nginx默认的keepalive_timeout是75秒,就算客户端设了更久,服务端也会主动关闭连接。
  • 你已经设置的limit_per_host=10是控制同一主机的并发连接数,这个配置没问题,不用改动。
  • 可以在服务端日志里确认下连接关闭的原因,排除是服务端主动断开的情况。

调整之后,再测试间隔15秒的请求,就能看到连接被复用,耗时保持在低水平了!

内容的提问来源于stack exchange,提问作者GAVIN HAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 15:57:30