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
相关产品推荐
相关产品推荐

