EMQX性能测试工具:从JMeter到自定义脚本
引言:解决物联网高并发性能测试痛点
在物联网(IoT)和工业物联网(IIoT)应用中,MQTT Broker的性能直接决定了系统的可靠性和可扩展性。随着设备连接数从百万级向亿级突破,传统测试工具往往难以模拟真实场景下的高并发负载。你是否曾面临JMeter脚本配置复杂、测试结果与生产环境偏差大的问题?本文将系统对比主流测试方案,从工具选型、场景设计到结果分析,提供一套完整的EMQX性能测试方法论,帮助你快速定位性能瓶颈,优化MQTT集群部署。
读完本文你将获得:
- 3种主流测试工具的优缺点对比及适用场景
- JMeter MQTT插件的高级配置指南(含TLS加密和QoS分级测试)
- 基于Erlang的自定义压测脚本开发框架
- 分布式测试环境的搭建与结果聚合方案
- 生产级性能基准数据与优化建议
一、性能测试工具选型:从通用到专业
1.1 工具对比矩阵
| 工具 | 核心优势 | 局限性 | 适用场景 | 并发能力 | 协议支持 |
|---|---|---|---|---|---|
| JMeter | 开源生态成熟、可视化界面、多协议支持 | 单机资源消耗高、脚本维护复杂 | 中小型集群测试、功能验证 | 单节点≤10万连接 | MQTT 3.1.1/5.0、TCP、HTTP |
| EMQX Benchmark | 专为EMQX优化、低资源消耗、集群感知 | 仅支持MQTT协议、学习曲线陡峭 | 大规模并发测试、性能调优 | 单节点≥50万连接 | MQTT 3.1.1/5.0、QUIC |
| Gatling | 高性能异步引擎、Scala DSL、实时报表 | 配置门槛高、社区资源有限 | 持续集成测试、性能回归 | 单节点≈30万连接 | MQTT扩展支持 |
1.2 架构选型流程图
二、JMeter测试实战:从基础配置到高级优化
2.1 环境准备与插件安装
-
基础环境配置
# 安装Java 17 (JMeter 5.6+推荐版本) sudo apt install openjdk-17-jdk -y # 下载JMeter 5.6.3 (国内镜像) wget https://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/apache-jmeter-5.6.3.tgz tar -zxf apache-jmeter-5.6.3.tgz # 安装MQTT插件 (国内CDN) cd apache-jmeter-5.6.3/lib/ext wget https://cdn.emqx.com/packages/jmeter-plugins/mqtt-xmeter-2.0.1.jar -
核心测试元件配置
元件类型 关键参数 优化建议 线程组 线程数=10000、 Ramp-Up=60秒、循环次数=永久 启用"调度器"设置测试时长 MQTT连接 服务器地址=emqx.example.com:1883、超时=30秒 启用"共享连接"减少资源消耗 发布采样器 QoS=1、消息大小=256B、间隔=100ms 使用"固定延迟"而非"均匀随机" 断言 响应时间<500ms、连接成功率=100% 添加"JSON断言"验证消息内容
2.2 TLS加密测试配置
<!-- jmeter.properties 配置TLS参数 -->
https.default.protocol=TLSv1.3
https.socket.protocols=TLSv1.3
mqtt.ssl.protocol=TLSv1.3
mqtt.ssl.keystore.type=PKCS12
mqtt.ssl.keystore.path=/opt/certs/client.p12
mqtt.ssl.keystore.password=emqx123
2.3 测试报告生成与分析
# 命令行模式执行测试并生成报告
./bin/jmeter -n -t emqx_perf_test.jmx -l results.jtl -e -o report/
# 关键指标提取 (使用JMeter Plugins CMD Reporter)
./bin/JMeterPluginsCMD.sh --generate-csv summary.csv --input-jtl results.jtl \
--plugin-type AggregateReport \
--aggregateReportIncludeMedian 1 \
--aggregateReportInclude90pct 1
报告关键指标解读:
- 连接建立成功率(应≥99.9%)
- 消息吞吐量(TPS,需区分不同QoS等级)
- P99延迟(生产环境建议≤200ms)
- 内存泄漏检测(关注JVM堆内存趋势)
三、EMQX Benchmark:Erlang原生压测工具
3.1 工具安装与基础用法
# 从源码编译 (需Erlang/OTP 25+)
git clone https://gitcode.com/gh_mirrors/em/emqx.git
cd emqx
make emqx_bench
./_build/emqx/bin/emqx_bench --help
# 基础连接测试 (10万连接,保持连接)
./_build/emqx/bin/emqx_bench conn \
--host 127.0.0.1 \
--port 1883 \
--number 100000 \
--interval 10 \
--keepalive 300
3.2 高级测试场景配置
10万连接+1万TPS混合测试:
./_build/emqx/bin/emqx_bench pub \
--host 127.0.0.1 \
--port 1883 \
--number 100000 \ # 总连接数
--topic bench/%i \ # 主题模板,%i会被替换为客户端ID
--qos 1 \ # QoS等级
--payload "Hello EMQX" \ # 消息内容
--size 256 \ # 消息大小(字节)
--rate 10000 \ # 总发送速率(TPS)
--interval 10 \ # 连接建立间隔(毫秒)
--duration 300 # 测试持续时间(秒)
3.3 分布式测试部署
四、自定义测试脚本开发:Python+Paho MQTT
4.1 基础框架设计
import time
import threading
import paho.mqtt.client as mqtt
from queue import Queue
class MQTTBenchClient:
def __init__(self, host, port, client_id):
self.client = mqtt.Client(client_id=client_id)
self.client.on_connect = self.on_connect
self.client.on_publish = self.on_publish
self.connected = False
self.publish_success = 0
self.host = host
self.port = port
def on_connect(self, client, userdata, flags, rc):
if rc == 0:
self.connected = True
else:
print(f"Connection failed with code {rc}")
def on_publish(self, client, userdata, mid):
self.publish_success += 1
def connect(self):
self.client.connect(self.host, self.port, keepalive=60)
self.client.loop_start()
def publish(self, topic, payload, qos=0):
if self.connected:
self.client.publish(topic, payload, qos=qos)
def disconnect(self):
self.client.loop_stop()
self.client.disconnect()
# 线程池管理类
class TestPool:
def __init__(self, host, port, total_clients, topics):
self.host = host
self.port = port
self.total_clients = total_clients
self.topics = topics
self.clients = []
self.queue = Queue(maxsize=1000)
def worker(self):
while True:
client_id = self.queue.get()
client = MQTTBenchClient(self.host, self.port, client_id)
client.connect()
self.clients.append(client)
self.queue.task_done()
def start(self, threads=10):
# 初始化工作队列
for i in range(self.total_clients):
self.queue.put(f"bench_{i}")
# 启动工作线程
for _ in range(threads):
t = threading.Thread(target=self.worker, daemon=True)
t.start()
self.queue.join()
print(f"All {self.total_clients} clients connected")
4.2 测试脚本集成Prometheus监控
from prometheus_client import Counter, Gauge, start_http_server
import time
# 定义监控指标
CONNECTIONS = Gauge('mqtt_bench_connections', 'Current MQTT connections')
PUBLISHED_MSG = Counter('mqtt_bench_published_messages', 'Total published messages')
PUBLISH_ERRORS = Counter('mqtt_bench_publish_errors', 'Total publish errors')
# 在测试循环中更新指标
while test_running:
CONNECTIONS.set(len(pool.clients))
try:
client.publish(topic, payload, qos=1)
PUBLISHED_MSG.inc()
except Exception as e:
PUBLISH_ERRORS.inc()
time.sleep(0.001) # 控制发布速率
四、分布式测试架构设计与实施
4.1 多节点协同测试拓扑
4.2 容器化测试环境部署 (Docker Compose)
version: '3'
services:
controller:
image: python:3.11-slim
volumes:
- ./scripts:/scripts
command: python /scripts/controller.py
environment:
- TARGET_HOST=emqx-node1
- TOTAL_CLIENTS=500000
- TEST_DURATION=300
ports:
- "9090:9090" # Prometheus暴露端口
worker-1:
image: emqx/emqx-bench:latest
command: ./emqx_bench pub --host emqx-node1 --number 200000 --rate 4000
depends_on:
- controller
worker-2:
image: emqx/emqx-bench:latest
command: ./emqx_bench pub --host emqx-node2 --number 300000 --rate 6000
depends_on:
- controller
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9091:9090"
五、性能测试最佳实践与优化建议
5.1 测试环境标准化配置
硬件推荐配置:
- CPU: Intel Xeon Gold 6330 (24C/48T) 或更高
- 内存: ≥64GB DDR4 ECC
- 网络: 10Gbps 以太网适配器
- 磁盘: NVMe SSD (测试数据与日志存储)
操作系统优化:
# 调整文件描述符限制
echo "* soft nofile 1048576" >> /etc/security/limits.conf
echo "* hard nofile 1048576" >> /etc/security/limits.conf
# TCP内核参数优化
sysctl -w net.ipv4.tcp_max_syn_backlog=16384
sysctl -w net.core.somaxconn=32768
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_fin_timeout=15
5.2 EMQX服务器优化参数
# emqx.conf 关键性能参数
listener.tcp.default.max_connections = 1000000
zone.external.max_inflight_messages = 1000
zone.external.message_queue_length = 10000
mqtt.max_packet_size = 1048576
# 集群优化
cluster.discovery = static
cluster.static.seeds = emqx-node1@192.168.1.10,emqx-node2@192.168.1.11
5.3 测试结果对比分析 (JMeter vs 自定义脚本)
| 测试场景 | 工具 | 连接数 | 吞吐量(TPS) | P99延迟(ms) | 资源消耗(CPU) |
|---|---|---|---|---|---|
| 纯连接测试 | JMeter | 10万 | - | 120 | 85% |
| 纯连接测试 | EMQX Bench | 10万 | - | 35 | 22% |
| 连接+发布(QoS 0) | JMeter | 5万 | 5000 | 180 | 92% |
| 连接+发布(QoS 0) | 自定义脚本 | 5万 | 15000 | 45 | 35% |
| 连接+发布(QoS 1) | 自定义脚本 | 5万 | 8000 | 98 | 42% |
六、总结与最佳实践指南
6.1 工具选型决策树
6.2 性能测试 checklist
测试前准备:
- 确认EMQX集群状态正常(
emqx_ctl cluster status) - 配置监控指标采集(Prometheus + Grafana)
- 备份EMQX配置文件
- 设置测试环境隔离(独立的测试网段)
测试中监控:
- 集群CPU/内存/网络使用率
- EMQX节点进程状态(
emqx_ctl processes) - 消息堆积情况(
emqx_ctl metrics show | grep messages) - 连接异常断开统计(
emqx_ctl listeners)
测试后分析:
- 生成性能测试报告(含对比基准)
- 检查EMQX日志中的错误信息
- 整理优化建议(配置调整、硬件升级等)
- 归档测试数据(供后续版本对比)
6.3 进阶学习资源
-
官方文档:
-
工具开发:
-
性能优化:
通过本文介绍的测试方法和工具,你可以构建一套完整的EMQX性能测试体系,从功能验证到生产级压力测试,全面保障物联网平台的稳定性和可靠性。记住,性能测试是一个持续迭代的过程,建议定期执行基准测试,跟踪系统性能变化趋势。
如果您在测试过程中遇到问题,欢迎通过EMQX社区论坛或GitHub Issue获取支持。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



