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

aiohttp ClientSession.post请求卡住且ClientTimeout超时设置失效如何解决

aiohttp超时未生效的核心原因

  • 你当前的代码仅获取了响应头对象,未完成响应体的读取/释放操作,ClientTimeout(total=5)的计时包含响应体接收全流程,部分场景下会卡在等待后续数据传输的阶段,无法触发超时
  • 低版本aiohttp存在代理连接阶段超时未纳入total计时的bug,使用代理时会出现全局超时配置不生效的问题
  • 全局会话的超时配置可能被单次请求的默认设置覆盖,导致配置不生效

解决方案

1. 补全响应读取/释放逻辑

每次获取resp对象后,不管是否需要响应内容,都主动调用resp.release()或者读取响应体,避免连接挂起:

async with session.post(url='https://www.quora.com/graphql/gql_para_POST?q=EditCredentialsModalQuery',
                        headers=headers, data=payload, proxy=self.proxy) as resp:
    if resp.status != 200:
        # 先释放响应再重试
        await resp.release()
        print(f'{user_name}[ModalQuery]: resp.status is not 200, retrying {req_time}\n')
        await asyncio.sleep(2)
        req_time += 1
        continue
    # 需要内容的话主动读取,结束请求流程
    res_data = await resp.json()

2. 升级aiohttp版本+双维度配置超时

首先升级aiohttp到3.8及以上版本,修复代理场景下的超时bug:
pip install --upgrade aiohttp
同时在创建全局会话和单次请求时都配置超时,避免全局配置失效:

# 全局会话初始化时配置超时
timeout = aiohttp.ClientTimeout(total=5)
session = aiohttp.ClientSession(timeout=timeout)

# 单次请求额外指定超时,覆盖默认参数
async with session.post(url='https://www.quora.com/graphql/gql_para_POST?q=EditCredentialsModalQuery',
                        headers=headers, data=payload, proxy=self.proxy,
                        timeout=aiohttp.ClientTimeout(total=5)) as resp:

3. 增加asyncio原生超时兜底

使用asyncio.wait_for包裹请求逻辑,作为最终超时兜底,哪怕aiohttp层超时失效也能强制抛出异常:

async with semaphore:
    while req_time <= 3:
        try:
            # 加6秒兜底超时,比aiohttp的超时多1秒留冗余
            resp = await asyncio.wait_for(
                session.post(url='https://www.quora.com/graphql/gql_para_POST?q=EditCredentialsModalQuery',
                            headers=headers, data=payload, proxy=self.proxy,
                            timeout=aiohttp.ClientTimeout(total=5)),
                timeout=6
            )
            async with resp:
                if resp.status != 200:
                    await resp.release()
                    print(f'{user_name}[ModalQuery]: resp.status is not 200, retrying {req_time}\n')
                    await asyncio.sleep(2)
                    req_time += 1
                    continue
                res_data = await resp.json()
                break
        except Exception as e:
            print(f'{user_name}[ModalQuery]: Async func get_cred_from_EditCredentialsModalQuery Error: {e}, '
                  f'retrying {req_time}')
            await asyncio.sleep(2)
            req_time += 1
            continue

4. 排查代理稳定性

代理节点连接故障时也会出现无响应的挂死情况,可在重试逻辑中加入代理切换逻辑,避免单节点故障导致程序卡住。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 01:57:01