Http请求:Address already in use : connect

一、异常场景

性能测试发送大量http请求时,出现了java.net.BindException: Address already in use: connect异常【注:发送http请求使用的是短连接】

 

 

二、原因分析

http网络通信一般用的是TCP进行传输

TCP使用四元组(源地址,源端口,目的地址,目的端口)来标识一个TCP套接字。

高并发场景下客户端会占用大量的端口,如果这些端口没有释放就会出现端口不够用的情况,抛出java.net.BindException: Address already in use: connect异常。

 

源端口不够用

windows电脑端口总共有65535个,其中

① 0~1023(共1024个)为公认端口,紧密的绑定在一些特定服务上,如21端口就是FTP服务,80端口就是HTTP服务;

② 1024~49151(共48127个)为注册端口,松散的绑定于一些服务,如8080端口常常用于绑定tomcat服务;

③ 49152~65535(共16384个)为动态或私有端口;

49152~65535端口可用于TCP通信,注册端口中的部分端口,也会用于TCP通信,所以一台电脑可用的通信端口数量会稍微比16384多一点,但是也不会多太多,大概是16400+ 个

 

正常的TCP客户端连接在关闭后,会进入一个TIME_WAIT的状态,持续的时间一般在1~4分钟,对于连接数不高的场景,1~4分钟其实并不长,对系统也会有什么影响,但如果短时间内容进行大量的短连接,则可能出现这样一种情况:客户端所在的操作系统的scoket端口被用尽,系统无法再发起新的连接。

 

查看TIME_WAIT连接的命令:

windows系统命令:

在cmd下执行如下命令

netstat -ano |findstr 端口 |find /i  "TIME_WAIT"

 

加上 /c 可统计TIME_WAIT连接个数

netstat -ano |findstr 端口 |find /i /c  "TIME_WAIT"

 

linux系统命令

netstat -an |grep -i "端口" | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

 

三、解决方案

一、对系统进行调优

修改系统注册表

1、打开注册表:regedit

2、进入

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\TCPIP\Parameters

3、新建 DWORD值,name:TcpTimedWaitDe,value:10(十进制) –> 设置为10秒,默认是240秒  【如果有这一项则修改,没有则新建】

4、新建 DWORD值,name:MaxUserPort,value:65534(十进制) –> 设置系统当前端口可用范围为65534 【如果有这一项则修改,没有则新建】

5、重启系统使注册表新增配置生效

 

 

 

二、使用长连接

短连接最大的优点是方便,但短连接最大的缺点是将占用大量的系统资源,例如:本地端口、socket句柄。我们可以通过使用长连接来避免这个问题。

 

 

 

 

posted @ 2022-12-19 13:46  harara  阅读(5599)  评论(0编辑  收藏  举报