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

Python AIOHTTP多次请求后性能骤降问题排查与解决

问题分析与解决方案

核心原因推测

1. TCP端口耗尽/连接池资源未合理管理

默认情况下,aiohttp的ClientSession未限制并发连接数,每轮1000个请求会快速占用大量系统临时端口。端口释放后会进入TIME_WAIT状态(通常持续几十秒),轮次增多后可用端口被耗尽,新请求只能等待端口释放,直接导致请求速度暴跌。

2. 未设置请求超时,慢请求拖垮整轮

部分请求因网络波动或服务器响应缓慢卡住时,无超时限制会拉长整轮执行时间,轮次积累后问题被放大。

3. 潜在资源泄漏

未处理请求异常、未及时清理连接资源,可能导致连接池无效连接堆积,或内存占用持续升高引发GC频繁执行,拖慢整体性能。

针对性解决办法

1. 限制并发连接数,优化连接池配置

给ClientSession配置TCPConnector,限制全局及单域名并发数,同时开启关闭连接自动清理:

import asyncio
import aiohttp

async def get_response(session, url):
    async with session.get(url) as resp:
        response_json = await resp.json()
        return response_json

async def main():
    # 配置连接池:根据系统性能调整参数
    connector = aiohttp.TCPConnector(
        limit=200,  # 全局最大并发连接数
        limit_per_host=50,  # 单个域名的最大并发连接数
        enable_cleanup_closed=True  # 自动清理已关闭的连接
    )
    async with aiohttp.ClientSession(connector=connector) as session:
        for _ in range(num_rounds):
            tasks = []
            # 给单轮请求设置统一超时
            timeout = aiohttp.ClientTimeout(total=10)
            for i in range(1000):
                url = f"some_url_{i}"  # 替换为实际URL生成逻辑
                tasks.append(asyncio.create_task(get_response(session, url)))
            
            # 捕获异常,避免单个请求失败导致整轮崩溃
            output = await asyncio.gather(*tasks, return_exceptions=True)
            # 可选:过滤异常结果
            # valid_output = [res for res in output if not isinstance(res, Exception)]
            
            # 显式清理变量,释放内存
            tasks.clear()
            output = None

if __name__ == "__main__":
    num_rounds = 20  # 替换为实际轮次
    asyncio.run(main())

2. 强制设置请求超时

可全局配置超时,或在单个请求中指定:

# 全局超时配置
async with aiohttp.ClientSession(
    connector=connector,
    timeout=aiohttp.ClientTimeout(total=10)
) as session:
    # 后续请求逻辑

3. 系统TCP参数优化(针对端口耗尽)

Linux系统可调整参数缩短TIME_WAIT时长、扩大可用端口范围(临时生效):

sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.ip_local_port_range="1024 65535"

注:tcp_tw_recycle在部分内核版本已废弃,优先使用tcp_tw_reuse。

4. 排查内存泄漏

若修改后仍有性能问题,可使用memory_profiler工具检测内存占用变化,定位是否存在未释放的大对象或循环引用。

验证效果

修改配置后观察每轮执行时间,若速度恢复稳定则说明是连接数/端口问题;若仍有波动,可通过tcpdump分析连接状态,进一步定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:54:55