使用Python requests调用CloudFlare API列出Zones时请求挂起的问题
脚本执行挂起的常见原因
对比可正常运行的curl实现与Python requests实现,出现curl能正常请求、Python脚本直接卡住的表现,基本是以下几个非常具体的原因导致:
- requests默认无超时机制造成无限等待
requests库的默认设计是不设置任何超时阈值,只要TCP连接建立成功,就会无限等待服务端返回响应。而curl自带较短的默认连接超时,遇到链路异常时会快速重试或报错退出,不会出现无限挂起的表现。
调试时可以先给请求加上明确的超时参数,比如在requests.get调用里补充timeout=10,最多等待10秒就会抛出对应错误,能快速定位是不是无限等待导致的假死。 - 自动读取失效代理配置导致连接阻塞
requests默认会自动读取系统环境变量中的http_proxy、https_proxy、all_proxy配置,如果这些代理地址已经失效(比如之前开过抓包工具、VPN,后来软件关闭了但环境变量没有同步清除),requests会一直尝试连接不可达的代理地址,且没有快速失败机制,外部表现就是脚本执行到请求步骤直接卡住没有输出。
排查时可以临时在请求参数中加入proxies={"http": None, "https": None},强制绕开所有代理配置直连目标接口,验证是否可以正常请求成功。 - IPv6链路无响应造成的连接卡滞
系统做域名解析时如果优先返回IPv6地址,而本地网络的IPv6出口本身不通,requests因为没有默认超时机制,会一直卡在尝试连接IPv6地址的阶段。而curl因为默认连接超时较短,会快速放弃IPv6尝试切换到IPv4地址,最终顺利完成请求。
这类问题通过缩短超时时间就能快速复现,调整DNS解析优先级、强制requests走IPv4链路即可解决。
排查时可以按顺序来:先给请求加上超时参数看具体报错,再绕开系统代理验证连通性,最后排查IPv6链路问题,基本可以覆盖绝大多数这类curl正常、requests挂起的场景。
内容的提问来源于stack exchange,提问作者Matthew Poletiek
相关产品推荐
相关产品推荐

