该问题困扰了我2周,尝试了各种办法无果后,最后终于找到问题原因,并做了记录。

服务器

  • centos 7.3

症状

  • 能正常 ping 通服务器的公网 IP
  • telnet 端口时,时而行时而不行
  • 公司同一网络下,有些同学能访问,有些不行,且也会出现断连的情况。如连接了 mysql 后,过一会就断开了。
    • 连手机的热点后,就能正常访问服务器和应用了。
  • ssh 登录也会出现 Operation Timed Out 的情况
  • 如果 ssh 能登录上服务器,ping baidu.com ,正常,且无网络掉频情况

处理结果

直接给出处理的办法,原因会在后面进行阐述。

修改 /etc/sysctl.conf

  1. $ vim /etc/sysctl.conf

添加如下内容

net.ipv4.tcp_timestamps = 0

保存退出后,生效内核参数

$ sysctl -p

处理效果

服务器恢复正常,同网络下所有同学都能正常访问应用和服务了。

经历过程

第一次处理

因为是云服务器,以为是安全组和防火墙的问题,于是关闭了防火墙,设置了安全组

  • 查看防火墙状态,如果是 active (running) 状态,进行关闭

    $ systemctl stop firewalld.service
    
  • 登录云主机控制台,查看安全组,发现 3306(mysql)已被添加

  • 然后观察,发现问题没解决

第二次处理

以为是服务器会话的发送频率导致超时

  • 修改 sshd_config

    $ vim /etc/ssh/sshd_config
    
  • 添加内容

    ClientAliveInterval 60
    ClientAliveCountMax 86400
    
  • 重启 ssh 服务

    $ systemctl restart sshd.service
    
  • 然后观察,发现问题没解决

第三次处理

以为是服务器连接总数不够

查看当前的有效运行连接数

$ netstat -nat|grep ESTABLISHED|wc -l

48

修改 ulimit,编辑文件 limits.conf

$ vim /etc/security/limits.conf

追加内容,保存

* soft stack 65535
* hard nproc 65535
* soft nproc 65535
* soft nofile 65535
* hard nofile 65535

修改 20-nproc.conf

$ vim /etc/security/limits.d/20-nproc.conf

内容如下,保存退出

* soft nproc
  • 重启服务器
  • 再次观察,没解决问题

第四次处理

经过前几次的处理,发现都不是问题所在,于是想到,可能是 IP 被占用,导致 TCP 连接没创建的问题,也就没有3次握手什么事了。

问题分析

只有在同一个网络下,很多人同时请求服务器时才会出现这样的情况,比如有4台机子请求了服务器,但是我们出去的都是同一个 公网 IP,当第一个人请求服务器后,建立了 TCP 连接,服务器记录了时间戳后,后面再请求的,时间戳都会大于之前的,服务器会直接忽略掉这个 syn,然后就无法完成 tcp 3次握手,表现为超时了。当空闲时,大家都是分时间段进行访问的,nat 端口使用率较低,不会出现这个情况;忙的时候,nat 使用率高,导致很难分到空闲的端口。

  • 当我们访问服务器时,如果建立了 tcp 连接,那么服务器会分配一个端口给这个连接,如:60776 端口
  • 当第二台服务器(同网)访问服务器时,服务器发现该 IP 已在服务器上存在,并忽略了此次访问,tcp 连接失败
  • 如果服务器的端口号段较少,也会出现这个情况,如果并发多的话,尽量放大些
    • ulimit -n:查看当前 tcp 可连接总数