从零开始搭建 EMQX 集群压测框架
架构
在设计以EMQX为中心的MQTT消息队列集群压力测试框架时,我们采用微服务架构模式。EMQX作为消息队列的核心,负责处理MQTT协议的消息发布和订阅。Nginx作为EMQX的反向代理,负责负载均衡和SSL/TLS终端。MQTTX-CLI作为压力测试工具,模拟大量客户端连接和消息交换。
流程
- 使用
Docker Compose
定义EMQX
集群服务、Nginx
服务和MQTTX-CLI
测试客户端。 EMQX
集群启动并等待客户端连接。Nginx
启动并配置为EMQX
集群的入口,处理来自外部的MQTT
连接请求。MQTTX-CLI
启动并模拟成千上万的客户端连接到Nginx
代理。- 收集测试数据,分析
EMQX
集群的性能和稳定性。
各服务功能
EMQX
:高性能的分布式MQTT
消息队列,处理消息发布、订阅和路由。Nginx
:反向代理服务器,提供负载均衡、SSL
终端、连接限制和访问控制。MQTTX-CLI
:命令行工具,用于模拟大量MQTT
客户端进行压力测试。
部署
使用Docker
和Docker Compose
进行服务的容器化部署。每个服务都被封装在独立的Docker
容器中,通过Docker
网络进行通信。Docker Compose
文件定义了服务的配置、网络和卷挂载。
文件目录
bash
|-- LICENSE
|-- README.md
|-- mqtt-lb-haproxy
`-- mqtt-lb-nginx
|-- README.md
|-- certs
| |-- cacert.pem
| |-- cert.pem
| |-- client-cert.pem
| |-- client-key.pem
| `-- key.pem
|-- docker-compose.yaml
|-- mqttx_cli_emqx_tcp.json
|-- mqttx_cli_emqx_tls.json
`-- nginx.conf
配置文件
yaml
version: '3'
services:
emqx1:
image: emqx/emqx:5.4.1
container_name: emqx1
hostname: emqx1-cluster.emqx.io
environment:
- EMQX_NODE__NAME=emqx1@emqx1-cluster.emqx.io
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static
- EMQX_CLUSTER__STATIC__SEEDS=emqx1@emqx1-cluster.emqx.io,emqx2@emqx2-cluster.emqx.io,emqx3@emqx3-cluster.emqx.io
ports:
- 18083:18083
networks:
- emqx-net
emqx2:
image: emqx/emqx:5.4.1
container_name: emqx2
hostname: emqx2-cluster.emqx.io
environment:
- EMQX_NODE__NAME=emqx2@emqx2-cluster.emqx.io
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static
- EMQX_CLUSTER__STATIC__SEEDS=emqx1@emqx1-cluster.emqx.io,emqx2@emqx2-cluster.emqx.io,emqx3@emqx3-cluster.emqx.io
networks:
- emqx-net
emqx3:
image: emqx/emqx:5.4.1
container_name: emqx3
hostname: emqx3-cluster.emqx.io
environment:
- EMQX_NODE__NAME=emqx3@emqx3-cluster.emqx.io
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static
- EMQX_CLUSTER__STATIC__SEEDS=emqx1@emqx1-cluster.emqx.io,emqx2@emqx2-cluster.emqx.io,emqx3@emqx3-cluster.emqx.io
networks:
- emqx-net
nginx:
image: nginx:1.23.0-alpine
container_name: nginx
ports:
- 1883:1883
- 8883:8883
- 8083:8083
- 8084:8084
- 8888:8888 # nginx status
volumes:
- $PWD/nginx.conf:/etc/nginx/nginx.conf
- $PWD/certs:/etc/nginx/certs
networks:
- emqx-net
mqttx-cli: # 指定压测工具
image: emqx/mqttx-cli
container_name: mqttx-cli
command: mqttx bench conn -c 2000 -h nginx # 对nginx容器进行压测
networks:
emqx-net: # mqttx-cli 与 其他容器 在同一局域网中
ipv4_address: 172.26.0.12
networks:
emqx-net:
driver: bridge
ipam:
config:
- subnet: 172.26.0.0/16
启动服务
bash
cd mqtt-lb-nginx && docker-compose up -d
# 查看服务运行状态
[root@master mqtt-lb-nginx]# docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
emqx1 "/usr/bin/docker-ent..." emqx1 running 0.0.0.0:18083->18083/tcp, :::18083->18083/tcp
emqx2 "/usr/bin/docker-ent..." emqx2 running 18083/tcp
emqx3 "/usr/bin/docker-ent..." emqx3 running 18083/tcp
mqttx-cli "docker-entrypoint.s..." mqttx-cli running
nginx "/docker-entrypoint...." nginx running 0.0.0.0:1883->1883/tcp ...
查看nginx子进程负载数
bash
# /home/nginx-cores.sh 需要在nginx 容器中先创建
[root@master mqtt-lb-nginx]# docker exec -it nginx cat /home/nginx-cores.sh
#!/bin/sh
nginx_pids=`ps aux |grep "[n]ginx: worker"|awk '{print $1}'`
for pid in $nginx_pids
do
n=`ls /proc/$pid/fd |wc|awk '{print $1}'`
echo "pid = $pid $n connection"
done
# 查看nginx子进程负载数
[root@master mqtt-lb-nginx]# docker exec -it nginx sh /home/nginx-cores.sh
pid = 174 1286 connection
pid = 175 1270 connection
pid = 176 1270 connection
pid = 177 1270 connection
pid = 178 1270 connection
pid = 179 1270 connection
pid = 180 1270 connection
pid = 181 1270 connection
emqx dashboard
访问地址:ip:18083
优劣势
优势:
- 容器化部署:快速部署和易于管理,确保环境一致性。
- 可扩展性 :
EMQX
集群和Nginx
可以水平扩展以处理更大的负载。 - 灵活性 :
Nginx
提供灵活的配置选项,如SSL、负载均衡策略等。 - 自动化测试 :
MQTTX-CLI
支持自动化测试脚本,提高测试效率。
劣势:
- 资源消耗:容器化可能占用较多的服务器资源。
- 复杂性 :
Docker
容器管理和服务编排增加了系统的复杂性。 - 网络配置:容器间的网络通信需要合理配置,以确保数据流畅。
- 性能评估 :通过压力测试,评估
EMQX
集群在高负载下的性能表现。
安全性考虑 :Nginx
作为反向代理,可以实施安全策略,如TLS加密和访问控制。
监控和日志 :集成监控系统,如Prometheus
和Grafana
,收集和分析性能数据。
通过综合考虑这些因素,可以设计并实现一个高效、可靠且易于维护的EMQX
集群压力测试框架。通过Docker
部署,我们能够实现快速、灵活的系统搭建和管理。