Python requests库HTTP请求需指定超时才完成的跨网络问题求助
问题分析与解决方案
核心问题拆解
你碰到的情况本质是请求卡在了TCP连接建立前的阶段:
- 不带
timeout时,请求一直挂着没反应,服务器端完全没收到请求记录 - 加了
timeout后,请求要等超时时间到了才真正发起并完成,严重拖慢性能测试
可能原因及修复方案
1. DNS解析阻塞
部分网络环境下系统DNS解析会卡住,而requests默认依赖系统DNS且没做超时控制,导致请求根本发不出去。
- 修复方式:
- 用自定义DNS解析后再发请求,比如借助
dnspython:import requests from dns import resolver # 切换到公共DNS服务器 resolver.default_resolver = resolver.Resolver(configure=False) resolver.default_resolver.nameservers = ['8.8.8.8', '1.1.1.1'] # 先解析域名拿到IP,再通过Host头指定原域名发起请求 target_ip = resolver.resolve('api.github.com')[0].address response = requests.get( f"https://{target_ip}", headers={'Host': 'api.github.com'}, timeout=5 ) print(response) - 检查并更换系统默认DNS为更稳定的公共服务。
- 用自定义DNS解析后再发请求,比如借助
2. 系统TCP连接超时配置过长
Windows/Linux默认的TCP SYN重试超时时间很长,requests没指定timeout时会沿用这个系统值,看起来就像请求"挂死"了。加timeout后,requests的超时逻辑可能存在触发延迟,导致请求在超时后才执行。
- 修复方式:
- 调整系统TCP参数:Windows修改注册表
TcpMaxConnectRetransmissions值;Linux修改/proc/sys/net/ipv4/tcp_syn_retries(需管理员权限) - 用
timeout元组分别设置连接超时和读取超时,精准控制:# 1秒内必须建立连接,3秒内必须拿到响应内容 print(requests.get("https://api.github.com", timeout=(1, 3)))
- 调整系统TCP参数:Windows修改注册表
3. requests 2.28.2版本bug
这个版本在特定网络环境下存在timeout参数处理逻辑的问题,导致请求触发延迟。
- 修复方式:
- 升级到最新稳定版:
pip install --upgrade requests - 或者降级到2.27.1这类之前的稳定版本测试。
- 升级到最新稳定版:
验证手段
- 用Wireshark或tcpdump抓包,确认卡住的阶段是DNS查询还是TCP握手
- 直接用IP访问目标地址,排除域名解析问题
内容的提问来源于stack exchange,提问作者John Curry
相关产品推荐
相关产品推荐

