网易云信IM系统中的Web版使用了Socket.IO实现浏览器环境下的长链服务;区别于常规的长链服务,为该服务的压测提出了一些新的挑战,本文总结了测试过程中的一些收获供参考。

Part1 测试工具选项

一、工具选型

  • Gatling

  • Node.js

  • JMeter

  • Java WebSocket

这些工具都是可以支持WebSocket协议的工具,主要从以下几个方面进行对比:

  • 上手难易程度

  • 测试资源开销

  • 和性能测试平台结合的难易程度

二、对比过程

对比场景

(1)5000个用户,每秒钟发送100个登录请求,并保持连接

(2)5000个用户,每隔5s发送一条点对点消息,即发送消息频率1000

工具使用过程

1. Gatling

工具简介:Gatling是一款基于Scala 开发的高性能服务器性能测试工具,它主要用于对服务器进行负载测试,并分析和测量服务器的各种性能指标。

工具语言:Scala语言

工具官网

http://gatling.io/docs/2.0.0-RC2/index.html#

相关代码

遇到的问题

(1)scale语言比较陌生,脚本编写时困难较多,目前暂未实现隔一定时间,即发心跳又发消息的场景;

(2)无法和性能测试平台结合,系统整合成本比较高;

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)整合到现有的性能测试平台

3. JMeter

工具简介:

JMeter是比较常见的性能测试开源工具,支持多种协议并且可以自定义java请求,更加灵活。

工具语言:

(1)Java

(2)JMeter xml脚本文件

工具官网:

http://jmeter.apache.org/usermanual/get-started.html

https://blog.flood.io/socket-io-and-websockets-with-gatling/

相关代码:

遇到问题:

JMeter的工具本上是同步的,如果建立1万个连接的话,需要启动1万个线程处理,因此不适合测试高并发长连接的场景。

4. Jetty WebSocket Client

工具简介:

Jetty提供了功能更强的WebSocket API,使用一个公共的核心API供WebSocket的服务端和客户端使用。

工具语言: Java

工具官网:

http://www.eclipse.org/jetty/

相关代码:

遇到问题:

需要自己写并发控制

三、对比结果总结

因为用来做性能压测,所以考虑到压测客户端需要实现高并发请求,选择Gatling和Socket.IO做了简单的对比测试。

Part2 长链服务端性能问题的定位

如第一部分所述,我们最终选择用Socket.IO实现了并发压测的长链客户端,下面简单说明下长链服务器端测试的一些收获;

首先,简单描述下被测试服务器的功能

1. 和前端Socket.IO客户端保持长连接;

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

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

1. 测试服务器可以支撑的最大连接数:该测试点涉及到了TCP连接,以及我们需要注意哪些参数,才可以保证用户建立的连接数目不会因为限制而达不到目标。

2. 每秒钟可以解析的包的数量:该测试点涉及到了网络流量,如果已经达到了网络流量的峰值时,会出现什么样的问题。

以下是这次测试过程中遇到的一系列问题:

问题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+

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

1. watch和netstat 两个命令

  • watch -d 定期查看一些信息,默认是2s;

  • netstat -st | grep ignored 查看TCP连接的一些统计信息;

可见有SYNs to LISTEN sockets ignored在不停增加,这表明收到连接建立过程中的三次握手的ACK包,但是因各种原因(包括accept队列满) 创建socket失败;

2. 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左右的连接可以建立成功;

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

  1. 通过netstat查看到send-q中有大量的消息堆积;

  2. 通过sar查看到有大量的重传;

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

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

  • 发送方/客户端:存在一定时间段发送出大量的重传包

  • 接收方/服务端:客户端发送大量重传包的这个过程中,什么都没有收到

这基本说明网络有问题

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

TCP的链接状态图

最后总结下在定位类似的网络问题中一些常规的命令、工具和关注的方向

可以使用以下命令

推荐使用以下工具

重点关注以下指标

点击下方“阅读原文”,技术干货

↓↓

记一次Socket.IO长链服务的性能压测相关推荐

  1. 软件性能测试分析与调优实践之路-JMeter对RPC服务的性能压测分析与调优-手稿节选

    一.JMeter 如何通过自定义Sample来压测RPC服务 RPC(Remote Procedure Call)俗称远程过程调用,是常用的一种高效的服务调用方式,也是性能压测时经常遇到的一种服务调用 ...

  2. 后端服务性能压测实践

    转自:https://mp.weixin.qq.com/s/XW9geHZ9odHdI7srDiKBIg 目录 背景 环境检测 压力机及压力工具检测 Linux openfiles limit 设置 ...

  3. Centos 异步 IO framework io_uring,基本原理,程序示例与性能压测

    尊重原创版权: https://www.conghengx.com/hot/37285.html 更多内容参考: https://www.conghengx.com/ Linux 异步 I/O 框架 ...

  4. 性能服务器图片介绍大图,服务端图片图片上传接口性能压测总结

    服务端图片上传接口性能压测总结 一.性能测试时需要关注点 用户操作的相应时间 服务器资源使用情况是否合理 应用服务器和数据库资源使用是否合理 系统能否实现扩展 系统最多支持多少用户访问.系统最大业务处 ...

  5. Fio工具详解【强大的IO性能压测工具】

    文章目录 Fio压测工具操作 常用参数 [time] [I/O tpye] [Blocks size] [Job description] [Threads, processes and job sy ...

  6. python服务端多进程压测工具

    本文描述一个python实现的多进程压测工具,这个压测工具的特点如下: 多进程 在大多数情况下,压测一般适用于IO密集型场景(如访问接口并等待返回),在这种场景下多线程多进程的区分并不明显(详情请参见 ...

  7. EMQ百万级MQTT消息服务(优化和压测)

    如果使用EMQ来承载百万级别的用户连接可以吗?官方的回复是8核心32G的配置能够承载160W台设备的链接,那就究竟性能如何呢?只有你自己试了才知道,本节就带着大家一起有调优系统配置和对EMQ进行压力测 ...

  8. 道路运输车辆卫星定位系统JT/T808服务实现和压测

    在工作上的需要接触道路运输车辆卫星定位系统相关应用,由于自己对网络服务的编写比较感兴趣,所以利用空闲时间实现了JT/T808的一些协议和相关服务(不得不说这种协议的设计在解释的确导致性能上的损耗,特别 ...

  9. 一文教你 Dubbo 服务性能压测(with JMeter)

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:为什么魂斗罗只有 128 KB却可以实现那么长的剧情?个人原创+1博客:点击前往,查看更多 原文地址:https ...

最新文章

  1. Python - while语句和if语句 的 用法 及 代码
  2. java.lang.IllegalAccessError: org.apache.commons.dbcp.DelegatingPreparedStatement.isClosed()Z
  3. java jpa 字段 关联_jpaQuery中查询字段是关联表的查询方法以及@JoinEntity(joinEntityAlias =str)的作用和代码编写的规范...
  4. editplus 快捷键
  5. bind简单转发实验
  6. 多线程 流水线 java_Java Lock锁多线程中实现流水线任务
  7. mysql长事务慢查询解决方案_MySQL : 如何监控和处理慢查询与长事务 ?
  8. Eclipse设置Courier New字体
  9. 风变Python3---if条件相关的学习
  10. 关于日期控件被模态框遮盖的问题解析
  11. mysql sys cpu_MySQL SYS CPU高的案例分析(一)
  12. 什么叫DMZ区?DMZ区它有什么作用?
  13. 2020全国工业互联网安全技术技能大赛Web题WP
  14. 假装写在了开头qwq
  15. 各类文件的文件头尾总结
  16. python学习-109-多个CSV文件的合并
  17. 2009年研究生数模竞赛中一道题是跟弹道学有关的, 我这里就搜罗了一些弹道学方面的历史材料
  18. 发现一个可视化大屏操作神器FBI,你值得一试
  19. Invoke 和 BeginInvoke 的真正涵义
  20. 28335 flash 下载到flash带仿真器可以,重新上电不能自动运行

热门文章

  1. BZOJ1085 [SCOI2005] 骑士精神
  2. mysql DbProviderFactories.GetFactory失败,解决方法
  3. HTML和URL比较
  4. 实例化bean的三种方式
  5. Java并发编程之ConcurrentHashMap
  6. 用户控件如何控制ASPX页面的控件
  7. .NET Framework 类库: Uri类
  8. ASP.Net分页组件1.0开发下载了...
  9. 第一次投稿怎么选杂志?
  10. MySQL(二)——DQL数据查询语言