FastAPI本地服务器请求端口耗尽问题及解决方案咨询
问题原因
你遇到的端口耗尽问题,核心是HTTP短连接的TIME_WAIT状态导致的:
- 默认情况下,requests每次发起请求都会新建一个HTTP短连接,请求完成后,客户端的socket不会立即释放,而是进入
TIME_WAIT状态(Windows系统默认时长为120秒),目的是确保网络中的残留报文被正确处理。 - 每一个处于TIME_WAIT的连接都会占用一个本地源端口,短时间内发起大量顺序请求时,可用的临时端口会被快速耗尽,最终抛出
WinError 10048错误。
解决方案
1. 使用requests会话复用连接(推荐)
用requests.Session()创建会话对象,所有请求通过该会话发送,会自动复用TCP连接,避免每次新建连接占用新端口:
import requests # 创建会话对象 session = requests.Session() # 所有请求通过session发送 response = session.post(rf"http://127.0.0.1:5000/endpoint1/", json={"arg1": "somevalue"}) # 后续请求复用同一个连接 response = session.post(rf"http://127.0.0.1:5000/endpoint2/", json={"arg2": "anothervalue"}) # 会话结束后关闭(可选,程序退出时会自动释放) session.close()
这样FastAPI日志里会看到所有请求来自同一个源端口,彻底解决端口耗尽问题。
2. 调整Windows系统的TCP参数(系统层面修改)
如果无法使用会话复用,可以修改系统注册表调整TIME_WAIT相关设置,减少端口占用时长或扩大临时端口范围:
缩短TIME_WAIT时长
- 打开注册表编辑器(运行
regedit) - 定位到
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters - 新建DWORD(32位)值,命名为
TcpTimedWaitDelay,设置值为30(单位:秒,范围0-300) - 重启系统生效
扩大临时端口范围
- 同样定位到上述注册表路径
- 新建DWORD(32位)值,命名为
MaxUserPort,设置值为65534(最大可用临时端口) - 新建DWORD(32位)值,命名为
TcpNumConnections,设置值为65534 - 重启系统生效
注意:修改注册表有风险,操作前请备份注册表。
3. 手动指定固定源端口(不推荐)
可以通过自定义HTTPAdapter绑定固定的本地端口,但这种方式可能导致端口冲突(如果该端口被其他程序占用),仅作为特殊场景下的备选方案:
import requests from urllib3.connection import HTTPConnection from urllib3.poolmanager import PoolManager class FixedPortHTTPAdapter(requests.adapters.HTTPAdapter): def __init__(self, source_port, **kwargs): self.source_port = source_port super().__init__(**kwargs) def init_poolmanager(self, *args, **kwargs): kwargs['source_address'] = ('', self.source_port) self.poolmanager = PoolManager(*args, **kwargs) # 使用固定端口(比如50000) session = requests.Session() adapter = FixedPortHTTPAdapter(50000) session.mount('http://', adapter) # 发起请求,所有请求都会使用50000作为源端口 response = session.post(rf"http://127.0.0.1:5000/endpoint1/", json={"arg1": "somevalue"})
内容的提问来源于stack exchange,提问作者Bram Vanroy
相关产品推荐
相关产品推荐

