🍯 测试环境介绍🥐 环境的连接稳定性🍞 测试说明🥖 测试结果表格🧀 一些总结🥚 测试数据截图序号1序号2序号3序号4序号5序号6序号7序号8序号9序号10序号11序号12序号13序号14序号15序号16序号17序号18序号19序号20序号21🥓 一些问题记录🥞 参考资料🧀 补充
在物联网时代,设备之间的通信变得越来越普遍,而 MQTT 作为轻量级的物联网协议,受到了越来越多的关注和应用。而 EMQX 作为一个高性能、高可靠、可扩展的 MQTT 消息服务器,成为了很多企业和开发者的选择。然而,在实际的生产环境中,EMQX 需要承受着大量的数据传输和处理,因此对其性能的测试就显得尤为重要。
本次对EMQX在连接保持、SSL、终结SSL等场景做了个测试,在这里记录并分享下结果。
🍯 测试环境介绍
宿主机5800H,宿主机系统为PVE,硬件信息和系统版本如下图

虚拟机系统为 Ubuntu 22.04 server,apt upgrade 到最新版本
虚拟机的硬件参数设置为

EMQX的server端,系统优化参考EMQX官方文档。对于作终结SSL的服务器(安装nginx和HAPorxy),也需要作相同的设置。
部分优化参数如
需要使用命令 `modprobe ip_conntrack` 打开对应模块,再设置
emqx.conf 配置文件
nginx 版本信息如下
Ubuntu22.04 安装 HAProxy 参考,本次安装的版本信息如下。
haproxy 配置文件参考EMQX官方推荐,这里的 emq.pem 文件,为emqx安装目录下,将cert.perm 和 key.pem 以文本形式合并。
🥐 环境的连接稳定性
在进行其他消息客户端与服务端之间保持60k连接接近一天,稳定在线。


同时从保持60k连接数,服务器CPU负载和内存占用率来看,在新建连接时候的成本比较高,在后续保持连接维护成本比较小。



🍞 测试说明
在实际测试验证的过程中,会先使用 `emqtt_bench` 命令pub稳定的消息数到EMQX服务器后,再启动sub客户端,待运行10分钟以上,负载稳定后,再通过PVE节点监控查看CPU占用率。
内存占用率由于一直占用较少(加上缓存大概4GB左右),且整个测试过程不会重启虚拟机,所以不关注内存占用率。
使用到的指令参考
`emqtt_bench` 命令参数如下
参数 | 简写 | 可选值 | 默认值 | 说明 |
--host | -h | - | localhost | 要连接的 MQTT 服务器地址 |
--port | -p | - | 1883 | MQTT 服务端口 |
--version | -V | 345 | 5 | 使用的 MQTT 协议版本 |
--count | -c | - | 200 | 客户端总数 |
--startnumber | -n | - | 0 | 客户端数量起始值 |
--interval | -i | - | 10 | 每间隔多少时间创建一个客户端;单位:毫秒 |
--interval_of_msg | -I | - | 1000 | 每间隔多少时间发送一个消息 |
--username | -u | - | 无;非必选 | 客户端用户名 |
--password | -P | - | 无;非必选 | 客户端密码 |
--topic | -t | - | 无;必选 | 发布的主题;支持站位符: %c:表示 ClientId%u:表示 Username%i:表示客户端的序列数 |
--szie | -s | - | 256 | 消息 Payload 的大小;单位:字节 |
--qos | -q | - | 0 | QoS 等级 |
--retain | -r | truefalse | false | 消息是否设置 Retain 标志 |
--keepalive | -k | - | 300 | 客户端心跳时间 |
--clean | -C | truefalse | true | 是否以清除会话的方式建立连接 |
--ssl | -S | truefalse | false | 是否启用 SSL |
--certfile | - | - | 无 | 客户端 SSL 证书 |
--keyfile | - | - | 无 | 客户端 SSL 秘钥文件 |
--ws | - | truefalse | false | 是否以 Websocket 的方式建立连接 |
--ifaddr | - | - | 无 | 指定客户端连接使用的本地网卡 |
🥖 测试结果表格
序号 | 连接数 | 连接服务器 | 每秒pub消息数 | 每秒sub消息数 | EMQX CPU使用率 | nginx CPU使用率 | HAProxy CPU使用率 |
1 | 5k | EMQX | 0 | 0 | 1.5% | 0 | 0 |
2 | 10k | EMQX | 0 | 0 | 1.5% | 0 | 0 |
3 | 20k | EMQX | 0 | 0 | 3% | 0 | 0 |
4 | 30k | EMQX | 0 | 0 | 5% | 0 | 0 |
5 | 5k | EMQX | 10k | 0 | 31% | 0 | 0 |
6 | 5k | EMQX | 20k | 0 | 40% | 0 | 0 |
7 | 5k | EMQX | 30k | 0 | 51% | 0 | 0 |
8 | 5k | EMQX | 10k(ssl) | 0 | 39% | 0 | 0 |
9 | 5k | EMQX | 20k(ssl) | 0 | 52% | 0 | 0 |
10 | 5k | EMQX | 30k(ssl) | 0 | 70% | 0 | 0 |
11 | 5k | EMQX | 10k | 10k | 37% | 0 | 0 |
12 | 5k | EMQX | 20k | 20k | 49% | 0 | 0 |
13 | 5k | EMQX | 10k(ssl) | 10k(ssl) | 50% | 0 | 0 |
14 | 5k | EMQX | 20k(ssl) | 20k(ssl) | 65% | 0 | 0 |
15 | 5k | EMQX | 10k | 20k | 41% | 0 | 0 |
16 | 5k | EMQX | 10k | 30k | 47% | 0 | 0 |
17 | 5k | EMQX | 10k(ssl) | 10k | 45% | 0 | 0 |
18 | 5k | EMQX | 10k(ssl) | 20k | 48% | 0 | 0 |
19 | 5k | EMQX | 20k(ssl) | 20k | 64% | 0 | 0 |
20 | 5k | EMQX | 10k | 10k(ssl) | 41% | 0 | 0 |
21 | 5k | EMQX | 20k | 20k(ssl) | 53% | 0 | 0 |
ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ |
22 | 5k | nginx | 0 | 0 | 1.3% | 0.3% | 0 |
23 | 10k | nginx | 0 | 0 | 1.4% | 0.2% | 0 |
24 | 30k | nginx | 0 | 0 | 4% | 0.5% | 0 |
25 | 5k | nginx | 10k | 0 | 32% | 10% | 0 |
26 | 5k | nginx | 30k | 0 | 61% | 24% | 0 |
27 | 5k | nginx | 10k(ssl) | 0 | 35% | 12% | 0 |
28 | 5k | nginx | 30k(ssl) | 0 | 71% | 37% | 0 |
29 | 5k | nginx | 10k | 10k | 43% | 13% | 0 |
30 | 5k | nginx | 10k(ssl) | 10k(ssl) | 42% | 16% | 0 |
31 | 5k | nginx | 10k | 10k(ssl) | 42% | 14% | 0 |
32 | 5k | nginx | 20k(ssl) | 20k(ssl) | 65% | 31% | 0 |
33 | 5k | nginx | 30k(ssl) | 30k(ssl) | 91% | 50% | 0 |
ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ | ㅤ |
34 | 5k | HAProxy | 10k(ssl) | 0 | 35% | 0 | 13% |
35 | 5k | HAProxy | 30k(ssl) | 0 | 74% | 0 | 40% |
36 | 5k | HAProxy | 10k(ssl) | 10k(ssl) | 45% | 0 | 17% |
37 | 5k | HAProxy | 20k(ssl) | 20k(ssl) | 67% | 0 | 33% |
38 | 5k | HAProxy | 30k(ssl) | 30k(ssl) | 91% | 0 | 53% |
🧀 一些总结
通过图标数据,可以得出一些基本关于EMQX的最佳实践和优化IoT框架方向。
1、只保持连接的资源占用较小。保持连接应该只有心跳间隔会稍微影响资源占用。新建连接的资源消耗都远大于保持连接,所以实际生产中,可以将连接数占用资源的影响排到最后,可以先考虑下实际的每秒新建连接数,或者说如何减少设备断联。
2、接收消息的成本大于转发消息的成本。一个主题消息转发给多个订阅客户端的CPU消耗比发送消息小,实践中尽量直接使用EMQX的转发,避免由业务层再转到另一个主题消息中。
3、SSL对EMQX需要额外消耗CPU资源,如果允许,可以避免使用SSL连接到到EMQX。受信的内部服务应直接连接EMQX的TCP端口。
4、虽然EMQX官方建议使用LB来终结SSL,但是在实际测试中,发现使用LB终结SSL再连接到EMQX,综合收益并没有明显提高,甚至在消息量上来时候,还需要额外多浪费LB服务器的成本。
5、对于EMQX官方推荐私有部署时的LB服务器,NGINX和HAProxy,两者终结SSL的性能差不多,选型时可能更多需要关注监控成本和生态问题。
🥚 测试数据截图
(多图预警!!!)
序号1



序号2



序号3



序号4



序号5



序号6



序号7



序号8



序号9



序号10



序号11



序号12



序号13




序号14



序号15




序号16




序号17

序号18




序号19




序号20




序号21




序号22





序号23




序号24




序号25




序号26



序号27




序号28



序号29



序号30



序号31



序号32



序号33




序号34



序号35



序号36



序号37



序号38



🥓 一些问题记录
1、在实际测试中,开始遇到了连接数到5w保持一段时间,emqx进程异常退出的情况,报错如下。
将deb安装的emqx删除,使用压缩包的方式运行后,报错更新成这样了

最后是更换了物理机的内存条才解决了问题
🥞 参考资料
tls_bench
silviucpp • Updated Oct 10, 2021
🧀 补充
后来在EMQX的官方论坛,询问了一下是否需要使用三方LB来终结TLS,链接:https://askemq.com/t/topic/5510 ,官方人员的建议还是使用成熟的模块去终结TLS,避免生产上的一些小问题。
至于提到的内存的差别,在我实际测试和生产环境上观察,在正常的4C8GB内存,或者8C16GB内存的等比例规格下,内存一般占用都很有限,还达不到需要关注的程度。

- 作者:Yibin
- 链接:https://yibin.dev/article/EMQX%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章












