Python requests无返回值但curl正常的技术问题求助
问题描述
用curl执行POST请求能正常接收20分钟后返回的响应:
curl --connect-timeout 2000 -d MY_JSON -H "Content-Type: application/json" -X POST MY_ADDRESS
但用Python requests库执行相同逻辑的请求时,服务器日志显示已发送响应,客户端却无法接收,仅当响应时长在10分钟以内时才能正常工作。已尝试调整timeout、添加verify=False、增加Accept请求头,均无效:
import requests data=MY_JSON requests.post(MY_ADDRESS, json=data, headers={'Content-Type' : 'application/json'})
可能的解决方案
- 正确设置timeout参数:requests的
timeout如果只传单个值,是连接超时和读取超时的总和。需要明确分开设置连接超时和读取超时,把读取超时设为足够覆盖20分钟的数值:# 连接超时2000秒,读取超时1200秒(20分钟) requests.post(MY_ADDRESS, json=data, headers={'Content-Type': 'application/json'}, timeout=(2000, 1200)) - 禁用连接池长连接:部分环境下,连接池的长连接可能被中间网络设备主动断开,尝试关闭会话的keep-alive:
import requests session = requests.Session() session.keep_alive = False response = session.post(MY_ADDRESS, json=data, headers={'Content-Type': 'application/json'}, timeout=(2000, 1200)) - 使用stream模式读取响应:如果响应内容较大,默认一次性读取可能触发隐性超时,改用stream模式分块读取:
response = requests.post(MY_ADDRESS, json=data, headers={'Content-Type': 'application/json'}, timeout=(2000, 1200), stream=True) # 逐块拼接响应内容 content = b''.join(response.iter_content(chunk_size=1024)) - 启用TCP keepalive:curl默认可能开启了TCP keepalive来维持长连接,而requests默认未配置,可手动添加该配置避免中间设备断开连接:
import requests import socket from urllib3.connection import HTTPConnection # 配置TCP keepalive参数 HTTPConnection.default_socket_options += [ (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), (socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60), # 闲置60秒后开始发心跳 (socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 10), # 心跳间隔10秒 (socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 6) # 连续6次心跳无响应则断开 ] session = requests.Session() response = session.post(MY_ADDRESS, json=data, headers={'Content-Type': 'application/json'}, timeout=(2000, 1200))
内容的提问来源于stack exchange,提问作者Ohad Kaiser
相关产品推荐
相关产品推荐

