问题的现象:
客户端登录平台服务器后经常掉线。
排查阶段1:
首先常规检查,磁盘容量没有问题、load average很低、cpu、mem使用率都不高、平台各服务配置、策略路由都反复检查过好几遍均没有问题。
由于客户端首先是通过nginx接入,所以下来查看nginx日志文件。此时发现nginx每天生成的日志文件大小将近有10G。
通过对日志进行分析得出非高峰时段对nginx中某个接口的每秒请求超过1200次。
对比使用平台的用户数(日均活跃用户400人左右),对该接口每秒1200次的请求显然是不正常的,但仍在nginx的承受范围内。
同一时段,观察到nginx所在服务器对后端服务器的转发经常超时,通过抓包发现转发包并没有能够发送(后端服务器也没有收到),怀疑nginx所在服务器连接资源可能存在问题。
使用ss -s命令查看发现,存在大量的timewait状态的socket连接,并且ports已经达到了系统设置的上限。
查阅相关资料,由于nginx使用短链接,因此在高频请求下会产生大量的timewait状态的socket连接、占用系统端口资源。
临时解决方法:
放大系统端口数量-如修改sysctl中net.ipv4.ip_local_port_range = 1024 65000
设置端口回收-修改sysctl中net.ipv4.tcp_tw_recycle = 1
但这只是治标不治本,时间一长端口仍然会被占满。
此后经过平台业务开发的修改业务代码,将对nginx请求数降低到了每秒100次以下,上述端口资源被占满的问题彻底解决。
排查阶段2:
然而就在上述问题解决后没多久我们就发现客户端掉线的问题依然存在,只是掉线频率下降了一些。
由于没有更好的排查手段,依然只能通过抓包,发现客户端到平台服务器有丢包现象。
ifconfig查看网卡信息发现RX packets中有大量的dropped包,
ethtool查看网卡信息Supported link modes: 100baseT/Full,即百兆网卡,因此怀疑是网卡性能不足。
由于该服务器是运行在kvm上的虚拟机,当时在配置虚拟机网卡时device model选择的默认Hypervisor default推测为百兆网卡,因此在虚拟机控制台中将网卡模型调整为e1000(千兆网卡)。
调整过后RX packets 不再出现dropped包
排查阶段3:
然后问题并没有得到缓解,掉线依旧。疑点是nginx所在服务器ping后端服务器丢包严重,但原因不明。
大家束手无策,只好请大拿出马。
大拿终究是大拿,不久就发现了问题:虽然load average的值很低,但是其中一个cpu的hi(硬中断)很高,接近满负荷。
通过查看/proc/interrupts,发现该cpu已被网卡中断拖垮,怀疑是虚拟机配置的网卡和cpu性能不足。
因此再次在虚拟机控制台中修改网卡模型为virtio(这个模型性能最好);调整cpu模型:copy host CPU configuration,调整pinning尽量使得与其他虚拟机不同时占用相同的物理机cpu。
解决结果:
通过上述调整,最终彻底解决了客户端掉线问题。