网络密集型产品性能问题定位思路和案例


最近在测试云信的link服务,该服务的主要功能是:

  1. 和前端socket io客户端保持长连接的服务
  2. 解析前端数据包,并作二次封装后抓发给后端APP服务,并且将后端APP服务转发过来的响应包转换成为socketio可以识别的json数据包,并发送给客户端

通过这两点功能,我们可以设计该产品的主要测试点为:

  1. 可以保持的最大链接数:从网络角度讲,该测试点涉及到了TCP链接,有哪些参数可以需要注意,才可以保证用户建立的连接数目不会因为限制而达不到目标。
  2. 每秒钟可以解析的包的数量:从网络的角度将,该测试点涉及到了网络流量,如果已经达到了网络流量的峰值,会出现什么样的问题。

下面,我整理了这次测试过程中遇到的一系列问题,分享给大家。


遇到问题1:最大连接数只能达到65000+

65535,对于程序员来说,这是一个很敏感的数字,因为一台服务器,限制的最大端口号即为65535,所以出现这个问题后:

  • 第一反应是:端口号不够用了?不对,link服务作为服务端,对外提供的服务端口仅有一个,所以不存在服务端端口号不够用的情况。
  • 第二反应:句柄数不够用了?文件句柄数相当于文件的标识符,建立一条socket链接,同样会使用一个文件句柄,而系统默认的单个进程使用的文件句柄为1024(?),对于这种需要保持大量链接的服务来说,一般情况下都是需要修改文件句柄数的,文件句柄数修改的方法如下:

      查看单个进程使用的最大文件句柄数的方法:
      ulimit -n
    
      如何知道当前进程打开了多少个文件句柄呢?下面一段小脚本可以帮你查看:
      lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more
    
      修改linux的最大文件句柄数限制的方法:
        1)ulimit -n 65535  
          在当前session有效,用户退出或者系统重新后恢复默认值
        2)修改profile文件:在profile文件中添加:ulimit -n 65535 
          只对当个用户有效
        3)修改文件:/etc/security/limits.conf,在文件中添加:
        (立即生效-当前session中运行ulimit -a命令无法显示)
    
      * soft nofile 32768 #限制单个进程最大文件句柄数(到达此限制时系统报警)  
      * hard nofile 65536 #限制单个进程最大文件句柄数(到达此限制时系统报错)  
    
      4)修改文件:/etc/sysctl.conf。在文件中添加:
      fs.file-max=655350 #限制整个系统最大文件句柄数  
      运行命令:/sbin/sysctl -p 使配置生效
    
  • 修改文件句柄的限制后,该问题依然没有得到解决?怎么办?这个时候,请使用dmesg:

    • dmesg命令显示linux内核的环形缓冲区信息,我们可以从中获得诸如系统架构、cpu、挂载的硬件,RAM等多个运行级别的大量的系统信息。‘dmesg’命令设备故障的诊断是非常重要的。
    • 通过dmesg,查看到了如下问题:

        [3105474.157029] nf_conntrack: table full, dropping packet.
        [3105474.157677] nf_conntrack: table full, dropping packet.
        [3105474.161147] nf_conntrack: table full, dropping packet.
      
    • conntrack表满了,那么contrack表是做什么的?

        nf_conntrack/ip_conntrack 跟 nat 有关,用来跟踪连接条目,它会使用一个哈希表来记录 established 的记录
        nf_conntrack 在 2.6.15 被引入,而 ip_conntrack 在 2.6.22 被移除,如果该哈希表满了,就会出现:
        nf_conntrack: table full, dropping packet
      
    • 如何修改conntrack表的大小

        net.netfilter.nf_conntrack_max = 65536
        net.ipv4.netfilter.ip_conntrack_max = 65536
        net.nf_conntrack_max = 65536
      
  • 到此为止,这个问题我们算是解决了,总结下,遇到的网络相关的知识点

    • 文件句柄
    • conntrack表


遇到的问题2:某些时候,链接只能建立3800+

注意,这个问题的前提是某些时候,也就是说明,这问题是偶现的。这种情况基本上可以排除是应用程序内部的问题。那对于这个问题我们使用了哪些定位手段呢?

  1. watch -d netstat -st : 两个命令
    1. watch -d,定期查看一些信息,默认是2s
    2. netstat -st,查看tcp链接的一些统计信息
    3. 这儿我们看到了:有SYNs to LISTEN sockets ignored在不停增加:这表明收到链接建立过程中的三次握手的ack包,但是因各种原因(包括accept队列满) 创建socket失败
  2. ss -ln : 查看进程对应的backlog的使用情况
    1. 什么是backlog:简单理解来说,链接已经在TCP层建立成功(完成了三次握手的过程)但是还没有被应用程序所接受,这种情况下,该链接会存放到backlog这样一个缓冲队列内
    2. 这儿我们看到了:应用程序的backlog队列已经满了,即便把这个值调整为1024,该队列还是会慢的

到这儿,我们的定位过程陷入了僵局,下一步该怎么定位呢?这期间我们查看了内存信息,CPU使用情况等,均没有找对地方:但是在定位过程中,我们发现,有时候jstack、jprofiler等工具都无法连上该服务了。

发挥机智的时候到了,突然想到:文件句柄是不是满了?又执行了几条命令:

  1. ls /proc/pid/fd | wc –l
  2. cat /proc/pid/limits

/proc/pid这个目录下了对应了所有在运行的进程的相关信息,

  1. 通过查看fd目录下的个数我们可以看到当前进程使用的文件句柄数有多少?
  2. 通过查看limits文件里面的值,可以看到系统对该进程的一些限制,不幸的是,出现这个问题的时候,max open files这个值被限制为了4096

但是查看该系统的文件句柄限制已经调整为了10w,为什么还有这个问题呢?继续验证

  1. 在服务器上重启该程序,该程序对应的max open files的值为10w
  2. 在OMAD上重启该程序,该程序对应的max open files的值为4096

终于定位到问题出现的原因了,那么产生的原因是什么呢?我们咨询OMAD的同事了解到:如果用户的open files 的max值是在omad agent启动后修改的,修改完成后,需要重新启动agent,避免这个问题。


遇到的问题3:大量的链接建立不成功

当我们解决了一个又一个的问题后,回归测试:突然发现,高压力下存在大量的链接建立不成功的问题,主要表现在:

  1. 原来:每秒钟500个链接建立的请求时,5w个用户都可以建立成功
  2. 现在:每秒钟500个链接建立的请求时,5w个用户只有4w左右的链接可以建立成功

这个问题也花费了不断的时间,我们使用了各种命令查看各种网络指标

  1. netstat:查看到send-q中有大量的消息堆积
  2. sar:查看到有大量的重传

后面整理的时候,总结起来,还是tcpdump抓包比较效果更好,从测试的开始,我们就只抓这一条链路上的包,且发送方和接收方,双方都抓包:

sudo tcpdump -i eth1 host classb-im7 and port 5010

然后通过wireshark分析,可以看到

  1. 发送方/客户端:存在一定时间段发送出大量的重传包
  2. 接收方/服务端:客户端发送大量重传包的这个过程中,什么都没有收到

这基本说明:网络有问题。

然后我们通过netperf测试了下网络带宽的情况:发现这两台机器之间的网络上限只有21Mb,而且测试过程中的网络请求量是超过这个值的。咨询云网络相关的同事发现,问题原因是因为云主机之间的网络QOS开启导致的,限制了每台云主机之间的网络带宽最高位21Mb,超过这个值则会被丢包。

附图:TCP的链接状态图

总结:常用的定位方法

请常使用以下命令

  • netstat -nap/-st等
  • ss -ln等
  • dmesg

请尝试用以下工具

  • tcpdump + wireshark

请常关注以下指标

  • open files的限制
  • conntrack表的限制
  • netstat recv-q 以及 send-q的值

备注

强烈推荐,组内赖东林同学的:网络性能测试手册,里面对相关概念的使用、工具的介绍、问题的定位思路等,介绍的非常详细。我在定位问题的过程中,这里面的内容让让我受益匪浅。




网易云新用户大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者侯本文授权发布。