乐趣区

记一次Socket.IO长链服务的性能压测

网易云信 IM 系统中的 Web 版使用了 Socket.IO 实现浏览器环境下的长链服务;区别于常规的长链服务,为该服务的压测提出了一些新的挑战,本文总结了测试过程中的一些收获供参考。Part1 测试工具选项一、工具选型 GatlingNode.jsJMeterJava WebSocket 这些工具都是可以支持 WebSocket 协议的工具,主要从以下几个方面进行对比:上手难易程度测试资源开销和性能测试平台结合的难易程度二、对比过程对比场景(1)5000 个用户,每秒钟发送 100 个登录请求,并保持连接(2)5000 个用户,每隔 5s 发送一条点对点消息,即发送消息频率 1000 工具使用过程
Gatling
工具简介:Gatling 是一款基于 Scala 开发的高性能服务器性能测试工具,它主要用于对服务器进行负载测试,并分析和测量服务器的各种性能指标。工具语言:Scala 语言工具官网:http://gatling.io/docs/2.0.0-… 相关代码:
遇到的问题:(1)scale 语言比较陌生,脚本编写时困难较多,目前暂未实现隔一定时间,即发心跳又发消息的场景;(2)无法和性能测试平台结合,系统整合成本比较高;
Node.js + Socket.IO
工具简介:Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I / O 的模型,使其轻量又高效;而 Socket.IO 是一个基于 Node.js 架构体系的且原生支持 WebSocket 协议,可用作实时通信的软件包。Socket.IO 为跨浏览器构建实时应用提供了完整的封装,且完全由 JavaScript 实现,语言更容易理解。工具语言:JavaScript 工具官网:• http://socket.io/docs/• http://nodejs.cn/ 相关代码:
遇到问题:(1)多节点并发分布式控制(2)整合到现有的性能测试平台
JMeter
工具简介:JMeter 是比较常见的性能测试开源工具,支持多种协议并且可以自定义 java 请求,更加灵活。工具语言:(1)Java(2)JMeter xml 脚本文件工具官网:http://jmeter.apache.org/user…https://blog.flood.io/socket-… 相关代码:
遇到问题 JMeter 的工具本上是同步的,如果建立 1 万个连接的话,需要启动 1 万个线程处理,因此不适合测试高并发长连接的场景。
Jetty WebSocket Client
工具简介 Jetty 提供了功能更强的 WebSocket API,使用一个公共的核心 API 供 WebSocket 的服务端和客户端使用。工具语言: Java 工具官网 http://www.eclipse.org/jetty/ 相关代码
遇到问题需要自己写并发控制三、对比结果总结因为用来做性能压测,所以考虑到压测客户端需要实现高并发请求,选择 Gatling 和 Socket.IO 做了简单的对比测试。
Part2 长链服务端性能问题的定位如第一部分所述,我们最终选择用 Socket.IO 实现了并发压测的长链客户端,下面简单说明下长链服务器端测试的一些收获;首先,简单描述下被测试服务器的功能

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

为此,我们确定该服务主要的测试点为

测试服务器可以支撑的最大链接数:该测试点涉及到了 TCP 链接,以及我们需要注意哪些参数,才可以保证用户建立的连接数目不会因为限制而达不到目标。
每秒钟可以解析的包的数量:该测试点涉及到了网络流量,如果已经达到了网络流量的峰值时,会出现什么样的问题。

以下是这次测试过程中遇到的一系列问题:问题 1:最大连接数只能达到 65K+65535,对于程序员来说,这是一个很敏感的数字,因为一台服务器,限制的最大端口号即为 65535,所以出现这个问题后:第一反应:端口号不够用了。分析认为 Link 服务作为服务端,对外提供的服务端口仅有一个,所以不存在服务端端口号不够用的情况;第二反应:句柄数不够用了。文件句柄数相当于文件的标识符,建立一条 socket 连接,同样会使用一个文件句柄,而系统默认的单个进程使用的文件句柄为 1024;对于这种需要保持大量连接的服务来说,一般情况下都是需要修改文件句柄数的,文件句柄数修改的方法如下:A)查看单个进程使用的最大文件句柄数的方法:
B)查看当前进程打开了多少个文件句柄呢:
C)修改 Linux 的最大文件句柄数限制的方法:1)ulimit -n 65535 在当前 session 有效,用户退出或者系统重新后恢复默认值 2)修改用户下的.profile 文件:在.profile 文件中添加:ulimit -n 65535 只对当前用户有效 3)修改文件 /etc/security/limits.conf,在文件中添加:(立即生效 - 当前 session 中运行 ulimit - a 命令无法显示)
4)修改文件 /etc/sysctl.conf 添加:
运行命令:/sbin/sysctl -p 使配置生效但是修改文件句柄的限制后,该问题依然没有得到解决。这个时候想到可以使用 dmesg 查看系统日志,dmesg 命令可以显示 Linux 内核的环形缓冲区信息,可以从中获得诸如系统架构、CPU 和挂载的硬件,RAM 等运行级别的大量系统信息, 因此 dmesg 命令在设备故障的诊断方面是非常重要的。通过 dmesg,查看到了如下问题:
从上面的信息可见 conntrack 表满了,那么 conntrack 表是做什么的?nf_conntrack/ip_conntrack 用来跟踪连接条目,会使用一个哈希表来记录 established 的记录 nf_conntrack 在 2.6.15 被引入,而 ip_conntrack 在 2.6.22 被移除,如果该哈希表满了 dmesg 命令就会出现:nf_conntrack: table full, dropping packet 如何修改 conntrack 表的大小
到此为止,这个问题我们算是解决了,总结下,遇到的网络相关的知识点包括 文件句柄 和 conntrack 表。问题 2:在某些用例场景下,稳定连接只能建立 3800+ 这个问题的前提是某些时候,也就是说偶现的,这种情况基本上可以排除是应用程序内部的问题。那对于这个问题我们使用了哪些定位手段呢?
watch 和 netstat 两个命令
watch -d 定期查看一些信息,默认是 2s;netstat -st | grep ignored 查看 TCP 连接的一些统计信息;可见有 SYNs to LISTEN sockets ignored 在不停增加,这表明收到连接建立过程中的三次握手的 ACK 包,但是因各种原因(包括 accept 队列满)创建 socket 失败;
ss -ln:查看进程对应的 backlog 的使用情况
backlog:简单理解来说,连接已经在 TCP 层建立成功(完成了三次握手的过程)但是还没有被应用程序所接受,这种情况下,该链接会存放到 backlog 这样一个缓冲队列内通过上面这个命令可以看到应用程序的 backlog 队列已经满了,但是即便把这个值调整为 1024,该队列还是会满的。到这儿,我们的定位过程陷入了僵局,下一步该怎么定位呢?这期间我们查看了内存信息,CPU 使用情况等,均没有找对地方;但是在定位过程中,我们发现,有时候 JStack、JProfiler 等工具都无法连上该服务了。突然想到文件句柄是不是满了?又执行了以下几条命令:
/proc/{pid} 这个目录下了对应了所有在运行的进程的相关信息,通过查看 /proc/{pid}/fd 目录下的个数我们可以看到当前进程使用的文件句柄数有多少。通过查看 limits 文件里面的值,可以看到系统对该进程的一些限制,不幸的是,出现这个问题的时候,max open files 这个值被限制为了 4096。调整该值之后最终解决了这个问题问题 3:大量的连接建立不成功当我们解决了一个又一个的问题后,突然发现高压力下存在大量的连接建立不成功的问题,主要表现在:原来:每秒钟 500 个连接建立的请求时,5w 个用户都可以建立成功;现在:每秒钟 500 个连接建立的请求时,5w 个用户只有 4w 左右的连接可以建立成功;这个问题也花费了不短 的时间,我们使用了各种命令查看各种网络指标通过 netstat 查看到 send- q 中有大量的消息堆积;通过 sar 查看到有大量的重传;总结起来还是 TcpDump 抓包比较效果更好,从测试的开始,我们就只抓这一条链路上的包,且发送方和接收方,双方都抓包:
然后通过 Wireshark 分析,可以看到发送方 / 客户端:存在一定时间段发送出大量的重传包接收方 / 服务端:客户端发送大量重传包的这个过程中,什么都没有收到这基本说明网络有问题然后我们通过 netperf 测试了下网络带宽的情况,发现这两台机器之间的网络上限只有 21Mb,而且测试过程中的网络请求量是超过这个值的。由于是在云主机环境上,通过咨询云网络相关的同事发现,问题原因是因为云主机之间的网络 QoS 开启限制导致的,限制了每台云主机之间的网络带宽最高位 21Mb,超过这个值则会被丢包。
TCP 的链接状态图最后总结下在定位类似的网络问题中一些常规的命令、工具和关注的方向可以使用以下命令
推荐使用以下工具
重点关注以下指标
想要获取更多产品干货、技术干货,欢迎关注网易云信博客。

退出移动版