赞
踩
接到一个项目需求,其中需要调用到供应商的Http API,因为有大量的测试资源,所以代码中会循环调用API。
然而在测试代码执行过程中,过程中偶尔报错:
此时看到报错,怀疑是可能是同时并发的问题,
但实际上并未对该接口进行限制,所以应该不是这个的问题, 进一步查看其他的报错的信息
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPSConnection object at 0x0C9C64F0>: Failed to establish a new connection: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
此错误原因指示是:一个通讯端口只能用一次
通过以下命令查看 TCP连接状态
ping host地址
netstat -ano | findstr IP
发现大量请TCP连接处于TIME_WAIT状态。
从上面TCP连接来看, 本地IP和服务端IP、服务端 端口都是固定不变的,而本地的端口是变化的。本地端口使用范围是 49152 -- 65535,总共16383个
从代码来看,因为是循环调用API,请求较多,导致大量请求处于TIME_WAIT状态,没有被释放,导致端口不够用。
那TIME_WAIT状态到底代表什么意思呢?
来看TCP三次握手四次挥手的过程
客户端在收到服务发送的FIN+ACK数据段后,向服务端发送一个ACK=1, seq=m+1, ack=+1数据段,之后就进入到TIME_WAIT状态时,此时TCP连接还没有完全释放,必须等待2MSL时间(一个MSL为2分钟),也就是4分钟之后才会进入到close状态, 以避免服务端没收到最后一个ACK报文。(Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”)
了解了以上原因,那总结下来原因是:
1、连接请求量过大
2、TIME_WAIT时间太长(4分钟),导致端口不能及时被释放
3、端口占用过多,导致本机端口数量不够
然而在结束执行程序(即结束全部的TCP连接)后, 再次进行代码执行时,发现请求次数还是有时没达10个就报错,可能是本机端口数量不够
所以最终解决方案:
1、减少TIME_WAIT时间, 修改TcpTimedWaitDelay
使用 regedit 命令访问 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/ Services/TCPIP/Parameters 注册表子键并创建名为 TcpTimedWaitDelay 的新 REG_DWORD 值。 将此值设置为十进制 30,其为十六进制 0x0000001e。该值将等待时间设置为 30 秒。 停止并重新启动系统。 缺省值:0xF0,它将等待时间设置为 240 秒(4 分钟)。 建议值:最小值为 0x1E,它将等待时间设置为 30 秒。
2、增加本机端口数量,修改MaxUserPort
MaxUserPort是一台主机向外连接使用端口数量的限制,这个数配置的,可能默认值才5000
使用 regedit 命令访问 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/TCPIP/Parameters 注册表子键并创建名为 MaxUserPort 的新 REG_DWORD 值。 重启系统。 该值的范围是从5000到65534,缺省值为5000,建议将该值设置为65534。
关于MaxUserPort参考: socket跟TCP/IP 的关系,单台服务器上的并发TCP连接数问题 - smile_lg - 博客园
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。