requests.post 小坑: 默认无超时,会阻塞

本文介绍了解决requests.post在Python中导致进程阻塞的问题,通过显式设置超时时间和重试机制,确保了进程不再因等待响应而卡住。同时,还详细解释了如何进一步细化超时设置。

一、遇到问题

最近遇到一个小问题 : 发现我的进程在调某个 API 的时候,不能正常 work 了。

马上一顿 strace -p pid 操作,定睛一看,
发现我的进程卡在了 recvfrom(23) 不动了,一直不会进入 accept 或者 epoll_wait ,
没有请求响应,也不会有任何的报错。

这时候才想起被requests.post 坑了,这货默认是阻塞的,除非显式指定了 timeout 值,否则不会做超时处理。

二、显式指定超时和重试

配置 requests 在经过 timeout( s )之后停止等待响应,从而避免进程一直卡住:  

try:
   requests.adapters.DEFAULT_RETRIES = 2
   response = requests.post(url, data = body, headers = http_headers, timeout=5 )
except Exception as ee:
   LOGGER.error(ee)

如此配置后,客户端在 timeout 秒内从基础套接字上必须接收到第一个字节数据, 否则就会抛出超时异常,不会再卡住了。
这里为了尽力收到数据,加了一次重试。

三、timeout 细化控制

前面配置的 “timeout=5” ,这个值是作为 connect 和 read 二者共用的 timeout ,

可以采用元组方式对这种单值超时方式进行细化,从而支持分别设置连接和读取阶段的超时时间。

connect 连接超时
指的是客户端实现到远端服务器端口的连接时 request 所等待的时间。
连接超时一般设为比 3 的倍数略大的一个数值,因为 TCP 数据包重传窗口的默认大小是 3。
read 读取超时
指的客户端已经连接上服务器并且发送了 request 后,客户端等待服务器发送请求的时间。
一般指的是服务器发送第一个字节之前的时间。

元组配置方式,比如:

response = requests.post(url, data = body, headers = http_headers, timeout=(3, 1) )

元组 timeout=(3, 1) 内第一个值为连接超时时间,第二个值为读取超时时间:
 

本文转载自:https://blog.youkuaiyun.com/weixin_44648216/article/details/105796379

使用 Python 的 `requests` 库请求 `http://8.130.147.152:8080/index.php` 时,可能会出现以下问题及相应的解决办法: ### 网络连接问题 - **问题描述**:可能由于网络故障、目标服务器未启动或被防火墙阻止等原因,导致无法建立与目标服务器的连接,抛出 `requests.exceptions.ConnectionError` 异常。 - **解决办法**: - 检查本地网络连接是否正常,可以尝试访问其他网站。 - 确认目标服务器是否正在运行,可以使用 `ping` 命令检查服务器的可达性。 - 检查防火墙设置,确保允许访问目标服务器的 IP 地址和端口。 ```python import requests url = 'http://8.130.147.152:8080/index.php' try: response = requests.get(url) print(response.text) except requests.exceptions.ConnectionError as e: print(f"网络连接错误: {e}") ``` ### 请求超时问题 - **问题描述**:如果服务器响应时间过长,超过了 `requests` 库的默认超时时间,会抛出 `requests.exceptions.Timeout` 异常。 - **解决办法**:可以通过设置 `timeout` 参数来调整超时时间。 ```python import requests url = 'http://8.130.147.152:8080/index.php' try: response = requests.get(url, timeout=10) # 设置超时时间为 10 秒 print(response.text) except requests.exceptions.Timeout as e: print(f"请求超时: {e}") ``` ### 服务器返回错误状态码 - **问题描述**:服务器可能返回 4xx 或 5xx 状态码,表示请求存在问题或服务器内部出现错误。 - **解决办法**:可以通过检查响应的 `status_code` 属性来判断请求是否成功,并根据不同的状态码进行相应的处理。 ```python import requests url = 'http://8.130.147.152:8080/index.php' response = requests.get(url) if response.status_code == 200: print(response.text) elif response.status_code >= 400 and response.status_code < 500: print(f"客户端请求错误,状态码: {response.status_code}") elif response.status_code >= 500: print(f"服务器内部错误,状态码: {response.status_code}") ``` ### SSL 验证问题 - **问题描述**:如果使用的是 HTTPS 协议,`requests` 库默认会进行 SSL 验证。如果服务器的 SSL 证书无效,会抛出 `requests.exceptions.SSLError` 异常。 - **解决办法**:可以通过设置 `verify=False` 来禁用 SSL 验证,但这样会存在安全风险,建议仅在测试环境中使用。 ```python import requests url = 'https://8.130.147.152:8080/index.php' try: response = requests.get(url, verify=False) print(response.text) except requests.exceptions.SSLError as e: print(f"SSL 验证错误: {e}") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值