Python requests执行REST请求后连接未关闭,如何避免出现悬空连接?
关于requests请求后出现TIME_WAIT状态的解决方案
核心原因澄清
你观察到的TIME_WAIT状态并非连接悬空,这是TCP协议的正常机制:主动发起连接关闭的一方,会在完成四次挥手后保持该状态2MSL(最长报文寿命,通常为1~2分钟),之后会被操作系统自动回收,不属于程序异常。
你调用response.close()的操作,本质是让客户端主动关闭TCP连接,所以客户端端口必然会进入TIME_WAIT状态,不是关闭操作没有生效。
正确优化方案
根据你的使用场景,可以选择以下任意一种方案解决:
- 方案1:使用
Session复用TCP连接(推荐,性能最优)
requests默认支持HTTP keep-alive长连接,使用全局Session对象管理请求可以复用TCP连接,避免频繁创建、销毁连接产生大量TIME_WAIT,不需要手动调用response.close():
# 类初始化时创建全局Session def __init__(self): self.session = requests.Session() def _deleteSensorById(self, id): URL = baseSensorsAPIsURL + "sensors/" + id # 用session实例发起请求,自动复用已有连接 response = self.session.delete(URL) self._checkStatusCode(response) # 无需手动关闭response,session会自动管理连接生命周期
- 方案2:禁用HTTP keep-alive,让服务端主动关闭连接
如果你的场景不需要长连接,可以在请求头中添加Connection: close,让服务端主动发起连接关闭,此时TIME_WAIT状态会出现在服务端,不会占用客户端端口:
def _deleteSensorById(self, id): URL = baseSensorsAPIsURL + "sensors/" + id # 添加header告知服务端关闭连接 headers = {"Connection": "close"} response = requests.delete(URL, headers=headers) self._checkStatusCode(response)
- 方案3:调整操作系统TCP参数(仅适合高并发场景)
如果短时间内会发起大量请求,TIME_WAIT端口占满导致无法新建连接,可以调整系统TCP参数开启TIME_WAIT快速回收和复用:- Windows系统:修改注册表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,添加TcpTimedWaitDelay键设置为30(缩短等待时间为30秒) - Linux系统:修改
/etc/sysctl.conf添加net.ipv4.tcp_tw_reuse = 1、net.ipv4.tcp_tw_recycle = 1,执行sysctl -p生效
- Windows系统:修改注册表
注意事项
绝大多数场景下不需要手动调用response.close(),该操作会强制断开可复用的长连接,反而会增加TIME_WAIT产生的概率。
内容的提问来源于stack exchange,提问作者user2164587
相关产品推荐
相关产品推荐

