linux 压测过程中返回 cannot assign requested address 及 Too many open files 问题

 

一.  cannot assign requested address 问题:

 

   这是由于 linux 分配的客户端连接端口号用尽,无法建立socket 连接导致的,虽然socket 正常关闭,但是端口不是立即释放的,而是处于 time_wait状态,默认等待60s 后释放  

  解决方案:

      调低time_wait 状态端口等待时间:

    1.调低端口释放后的等待时间,默认为60s,修改为15-30秒

               sysctl -w net.ipv4.tcp_fin_timeout=30

    2.修改tcp/ip 协议配置,通过配置

        net.ipv4.tcp_timestamps = 1

       net.ipv4.tcp_tw_reuse = 1  (time_wait socket 快速重启)          

    

 netstat  -ant|grep TIME_WAIT|wc -l     查看当前实例上处于  TIME_WAIT 状态连接数,   一般未出现 socket 无法连接,且未超过 系统上限65535 ,可忽略不计

 

 

二.Too many open files 问题 :

   原因分析:在服务器与客户端通讯过程中,因服务器发生socket 未关闭导致的close_wait 发生,致使监听的port打开的句柄数达到了1024个,且处于close_wait 的状态,最终造成配置的port 被占满出现"too many open files",无法进行通讯

        close_wait 状态出现的原因是被动关闭方未关闭socket 造成的

                netstat  -ant|grep TIME_WAIT|wc -l       查看当前实例上处于  TIME_WAIT 状态连接数

在 Linux 上可用以下语句看了一下服务器的TCP状态(连接状态数量统计):

      netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'   

      netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c

一、解决:
原因是因为调用ServerSocket类的accept()方法和Socket输入流的read()方法时会引起线程阻塞,所以应该用setSoTimeout()方法设置超时(缺省的设置是0,即超时永远不会发生);超时的判断是累计式的,一次设置后,每次调用引起的阻塞时间都从该值中扣除,直至另一次超时设置或有超时异常抛出。
比如,某种服务需要三次调用read(),超时设置为1分钟,那么如果某次服务三次read()调用的总时间超过1分钟就会有异常抛出,如果要在同一个Socket上反复进行这种服务,就要在每次服务之前设置一次超时。
二、规避:
调整系统参数,包括句柄相关参数和TCP/IP的参数;

注意:
/proc/sys/fs/file-max 是整个系统可以打开的文件数的限制,由sysctl.conf控制;
ulimit修改的是当前shell和它的子进程可以打开的文件数的限制,由limits.conf控制;
lsof是列出系统所占用的资源,但是这些资源不一定会占用打开文件号的;比如:共享内存,信号量,消息队列,内存映射等,虽然占用了这些资源,但不占用打开文件号;
因此,需要调整的是当前用户的子进程打开的文件数的限制,即limits.conf文件的配置;
如果cat /proc/sys/fs/file-max值为65536或甚至更大,不需要修改该值;
若ulimit -a ;其open files参数的值小于4096(默认是1024), 则采用如下方法修改open files参数值为8192;方法如下:
1.使用root登陆,修改文件/etc/security/limits.conf
vi /etc/security/limits.conf 添加
xxx - nofile 8192
xxx 是一个用户,如果是想所有用户生效的话换成 * ,设置的数值与硬件配置有关,别设置太大了。
#<domain>      <type>     <item>         <value>

*         soft    nofile    8192
*         hard    nofile    8192

#所有的用户每个进程可以使用8192个文件描述符。
2.使这些限制生效
确定文件/etc/pam.d/login 和/etc/pam.d/sshd包含如下行:
session required pam_limits.so
然后用户重新登陆一下即可生效。
3. 在bash下可以使用ulimit -a 参看是否已经修改:

一、 修改方法:(暂时生效,重新启动服务器后,会还原成默认值)
sysctl -w net.ipv4.tcp_keepalive_time=600  
sysctl -w net.ipv4.tcp_keepalive_probes=2
sysctl -w net.ipv4.tcp_keepalive_intvl=2

注意:Linux的内核参数调整的是否合理要注意观察,看业务高峰时候效果如何。

二、 若做如上修改后,可起作用;则做如下修改以便永久生效。
vi /etc/sysctl.conf

若配置文件中不存在如下信息,则添加:
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15

 

 

 

 

 

net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 10
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_tw_buckets = 6000
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_keepalive_time = 30

 

 

 

 

 

 

 

 

 

编辑完 /etc/sysctl.conf,要重启network 才会生效
/etc/rc.d/init.d/network restart
然后,执行sysctl命令使修改生效,基本上就算完成了

 

 

       

 

posted @ 2022-12-09 11:59  阿_源  阅读(709)  评论(0)    收藏  举报