服务器介绍
环境介绍
BladeX 物联网平台基于 Java 开发,可部署在 Linux、Windows 等操作系统上,生产环境推荐使用 Linux(Ubuntu、Debian 等)。运行环境要求 JDK 21、MySQL 8、Redis 7,时序库可选 TDengine、InfluxDB 或 IoTDB。服务器配置取决于部署模式、同时在线设备数和消息量,可按本文的估算方法和参考配置选型。
1. 服务说明
| 服务 | 单机模式 | 集群模式 | 推荐内存 |
|---|---|---|---|
| blade-server | 管理后台与开放接口,下行指令经 broker 的 HTTP 接口下发 | 同单机模式 | 1G~2G |
| blade-broker | MQTT 接入与认证、场景联动与服务端订阅匹配、数据处理与入库 | MQTT 接入与认证、场景联动与服务端订阅匹配;上行消息写入 Kafka,下行消息投递给本节点的设备 | 2G 起,每 10 万连接约需 6G |
| blade-data | 不部署 | 消费 Kafka 中的上行消息,完成时序库入库、设备日志、设备状态、设备影子与 OTA 处理 | 2G 起,随消息量增加 |
- 单机模式:消息在 blade-broker 进程内处理完毕,不依赖 Kafka。MySQL、Redis 与时序库可以与平台同机部署,也可以拆分到独立服务器。
- 集群模式:blade-broker 改用集群实现(
blade-broker-cluster与blade-mq-kafka),接入与数据处理经 Kafka 解耦,blade-broker 与 blade-data 都可以多实例部署。部署步骤见启动后端(集群模式)。
官方镜像的启动命令没有指定堆内存,JVM 默认最大堆只有可用内存的 1/4。部署时需要按上表显式设置,例如通过环境变量 JAVA_TOOL_OPTIONS=-Xms6g -Xmx6g 传入。
2. 容量估算
2.1 关键指标
| 指标 | 主要影响 |
|---|---|
| 同时在线设备数 | 每条 MQTT 长连接都占用 broker 的堆内存和文件句柄,每 10 万连接约需 6 GB 堆内存 |
| 消息量(条/秒) | broker 与 blade-data 的 CPU、Kafka 吞吐、时序库写入 |
| 报文大小与数据保留周期 | 公网带宽,以及 Kafka 与时序库的磁盘容量 |
| 连接与重连频率 | 设备认证、认证日志写入和设备状态更新,集中重连时形成瞬时峰值 |
同时在线设备数指同一时刻保持连接的设备数,不是平台中注册的设备总数。
2.2 消息量
消息量 = 同时在线设备数 ÷ 上报间隔(秒)。有下行指令时,再加上下行消息量。
| 同时在线设备 | 每 10 秒上报 | 每 30 秒上报 | 每分钟上报 | 每 5 分钟上报 |
|---|---|---|---|---|
| 1 万 | 1,000 条/秒 | 333 条/秒 | 167 条/秒 | 33 条/秒 |
| 10 万 | 10,000 条/秒 | 3,333 条/秒 | 1,667 条/秒 | 333 条/秒 |
| 30 万 | 30,000 条/秒 | 10,000 条/秒 | 5,000 条/秒 | 1,000 条/秒 |
| 100 万 | 100,000 条/秒 | 33,333 条/秒 | 16,667 条/秒 | 3,333 条/秒 |
一条上行消息在平台内部还会产生以下处理量:
- 时序库:属性、事件等数据写入 1 行,设备日志再写入 1 行(默认开启),写入行数约为消息量的 2 倍。
- Kafka(集群模式):消息写入对应的业务主题,同时写入集群交换主题
blade_cluster_exchange;属性上报的回复经下行主题blade_links_msg_down发回设备。
单机部署和分机部署要同时满足在线设备数和消息量两项设计规模,任一项超出都应升级档位。集群部署中,broker 按在线设备数扩展,blade-data、Kafka 与时序库按消息量扩展。例如 10 万台设备每 10 秒上报一次,消息量达到 1 万条/秒,超出分机部署的设计规模,应采用集群部署:broker 按 10 万在线配置,其余组件按 1 万条/秒配置。
2.3 带宽
公网带宽 ≈ 消息量 × 单条报文大小 × 8。以单条报文 300 字节为例:
| 设计规模 | 消息量 | 平均带宽 | 建议带宽 |
|---|---|---|---|
| 10 万在线,每分钟上报 | 1,667 条/秒 | 约 4 Mbps | 5M 以上 |
| 30 万在线,每分钟上报 | 5,000 条/秒 | 约 12 Mbps | 20M 以上 |
| 100 万在线,每分钟上报 | 16,667 条/秒 | 约 40 Mbps | 50M 以上 |
实际带宽还要计入 MQTT 心跳、QoS 1 确认报文、TLS 加密和下行指令的开销。服务器之间通过内网通信,集群模式的内网流量见第 5 章。
2.4 存储
时序库磁盘 ≈ ∑(每日原始数据 × 保留天数)÷ 压缩比 × 副本数,分两部分计算:
- 属性与事件数据:保留天数由
tdengine.keep设置,默认 3650 天。 - 设备日志:写入独立的
links_log库,保存原始报文,保留天数由tdengine.device-logs-keep设置,默认 180 天;不需要时可设置tdengine.enable-device-logs: false关闭。
TDengine 的压缩比通常不低于 5 倍;设备日志是文本,压缩比一般低于数值型数据,以实测为准。以属性单行 100 字节、报文 300 字节、5 倍压缩、单副本为例:
| 设计规模 | 属性数据(保留 1 年) | 设备日志(保留 180 天) | 合计 |
|---|---|---|---|
| 10 万在线,每分钟上报 | 约 1.05 TB | 约 1.56 TB | 约 2.6 TB |
| 30 万在线,每分钟上报 | 约 3.15 TB | 约 4.67 TB | 约 7.8 TB |
| 100 万在线,每分钟上报 | 约 10.5 TB | 约 15.6 TB | 约 26 TB |
设备日志通常占时序库磁盘的一半以上。消息量较大时,可按排障需要缩短设备日志的保留期。
Kafka 单节点磁盘 ≈ 写入速率 × 保留时长 × 副本数 ÷ 节点数,3 节点 3 副本时每个节点保存全量数据。业务主题默认保留 7 天(log.retention.hours=168),消息量大时可缩短到 1~3 天;集群交换主题由平台创建,保留 1 小时。以保留 3 天为例,上行消息与回复合计约 400 字节/条时,30 万在线每个节点约需 0.5 TB,100 万在线约需 1.7 TB。
2.5 峰值
以下两类峰值在平均值中体现不出来,规划时要单独考虑:
- 集中重连:平台重启、网络恢复或断电恢复后,大量设备在短时间内同时重连。每次连接都要完成认证(设备信息优先读 Redis 缓存,未命中时查询 MySQL),并写入认证日志
iot_mqtt_auth_log、批量更新设备状态。设备端重连应采用随机退避。 - 同步上报:设备在整点等固定时刻集中上报时,瞬时消息量远高于平均值。设备端的上报时刻应加入随机偏移。
各服务器常态 CPU 使用率建议控制在 50% 以内,为峰值留出余量。认证日志不会自动清理,设备规模较大时需要定期归档或清理。
3. 单机部署
适用于开发测试、功能验证和小规模生产。平台服务与全部中间件部署在同一台服务器。
| 项目 | 配置 |
|---|---|
| CPU | 4 核 8 线程 |
| 内存 | 8 GB |
| 磁盘 | SSD 40 GB,生产环境 100 GB 起 |
| 操作系统 | Linux |
| 部署内容 | MySQL、Redis、时序库、blade-server、blade-broker |
时序库建议选择 TDengine 或 InfluxDB。IoTDB 对内存要求较高,8 GB 内存的服务器不建议使用。
设计规模
同时在线设备不超过 1 万台,消息量低于 1,000 条/秒。
4. 分机部署
适用于 10 万设备级、分钟级上报的生产环境。平台仍以单个 blade-broker 运行,MySQL、Redis 与时序库拆分到独立服务器,避免中间件与 broker 争用 CPU 和内存。
| 服务器 | 配置 | 部署内容 | 公网带宽 |
|---|---|---|---|
| Web 服务器 | 2 核 4G,硬盘 40G | Nginx、前端页面、blade-server | 5M 以上 |
| Broker 服务器 | 4 核 8G,硬盘 40G | blade-broker,JVM 堆内存 6G | 5M 以上 |
| 数据库服务器 | 4 核 8G,SSD 100G | MySQL、Redis | 1M 以上 |
| 时序库服务器 | 4 核 8G,SSD 3T | TDengine、InfluxDB 或 IoTDB | 1M 以上 |
设计规模
同时在线设备 10 万台,每台每分钟上报一次,消息量约 1,700 条/秒。
单个 blade-broker 没有故障转移能力,节点宕机期间设备无法接入。对可用性有要求,或者在线设备数、消息量超出上述规模时,应采用集群部署。
5. 集群部署
5.1 架构
- 接入:Nginx stream 对外提供 1883(MQTT)、8883(MQTT over TLS)、8083(WebSocket)、8084(WebSocket over TLS)端口,按设备源 IP 一致性哈希(
hash $remote_addr consistent)选择节点,设备重连时优先回到原节点。TLS 在 Nginx 终结。1883、8883 通过 PROXY 协议把设备真实 IP 传给节点,节点需开启mqtt.server.proxy-protocol-on。 - 上行:broker 把消息写入 Kafka 对应的业务主题,由 blade-data 消费后写入时序库,并更新设备状态与影子。
- 下行:blade-server 调用任一 broker 节点的 HTTP 接口,消息写入
blade_links_msg_down。每个节点都会消费下行主题,只有设备所在的节点实际投递,平台不需要知道设备连在哪个节点。 - 节点管理:每个 broker 节点启动时生成独立的 Kafka 消费组,以广播方式消费集群主题,增减节点不需要修改其他节点的配置。
5.2 扩展规则
- blade-broker:
- 单节点可承载的连接数按堆内存估算,每 10 万连接约需 6 GB 堆内存。节点数 = 在线设备数 ÷ 单节点连接数(向上取整)+ 1,多出的一台用于在单节点故障时承接重连设备。
- 每个节点都要消费全量的集群交换消息、属性消息和下行消息,约为全网上行消息量的 2~3 倍。这部分负载不随节点数分摊,Kafka 的出口流量还会随节点数线性增长,因此宜选用较大规格的节点,控制节点数量。
- 接入层:Nginx 到同一节点端口的连接受本机临时端口范围限制,每个出口 IP 在默认端口范围下约 2.8 万条,
net.ipv4.ip_local_port_range调整为1024 65535后约 6.4 万条。单节点连接数超过这个数时,需要给 Nginx 配置多个出口 IP(proxy_bind),或者改用保留客户端源地址的负载均衡。 - blade-data:
- 每个实例对每个 Kafka 主题只有 1 个消费线程,同一主题的并行度 = min(实例数,分区数)。Kafka 自动创建主题时分区数取
num.partitions,要不小于计划的实例数。 - 4 核 8G 实例按约 2,000 条/秒规划,8 核 16G 实例按约 4,000 条/秒规划,至少部署 2 个实例。Kafka 消费积压持续增长时扩容。
- 每个实例对每个 Kafka 主题只有 1 个消费线程,同一主题的并行度 = min(实例数,分区数)。Kafka 自动创建主题时分区数取
- Kafka:3 节点 KRaft 集群,业务主题 3 副本(
default.replication.factor=3、min.insync.replicas=2),部署方式见消息队列。 - 时序库:推荐 TDengine 或 IoTDB 集群。InfluxDB 开源版不支持集群,需要时序库高可用时不要选择。
- MySQL、Redis:MySQL 采用主从;Redis 采用主从加哨兵,或者 Redis Cluster。Redis 缓存设备信息,内存随设备总数增长。
5.3 设备侧要求
- 自动重连:节点故障后,设备要自行重连,由 Nginx 分配到其他可用节点。
- 重连后重新订阅:订阅关系保存在节点内存中,换到其他节点后原订阅不存在。Paho 客户端在
cleanSession=true时不会自动补订阅,需要在连接成功的回调中重新订阅。 - keepalive 取 30~60 秒:既能及时发现失效连接,又要小于 Nginx 的
proxy_timeout。 - 节点之间不共享会话:未确认的 QoS 1/2 消息、保留消息和遗嘱消息保存在节点内存中,切换节点后不保留。重要指令需要由业务层回包确认或重发。
5.4 中型集群(30 万在线)
设计规模
同时在线设备 30 万台,每台每分钟上报一次,消息量约 5,000 条/秒。
| 角色 | 数量与配置 | 部署内容 |
|---|---|---|
| 接入服务器 | 2 台 4 核 8G | Nginx stream + Keepalived,配置多个出口 IP;公网带宽 20M 以上 |
| Web 服务器 | 2 台 4 核 8G,硬盘 40G | Nginx、前端页面、blade-server |
| Broker 服务器 | 3 台 8 核 16G,硬盘 40G | blade-broker,JVM 堆内存 12G,单节点约 20 万连接 |
| Data 服务器 | 3 台 4 核 8G,硬盘 40G | blade-data |
| Kafka 服务器 | 3 台 4 核 8G,SSD 1T | Kafka 3 节点集群 |
| 数据库服务器 | 2 台 4 核 8G,SSD 200G | MySQL 主从 |
| 缓存服务器 | 3 台 2 核 4G | Redis 一主两从加哨兵 |
| 时序库服务器 | 1 台 8 核 16G,SSD 10T | TDengine、IoTDB 或 InfluxDB |
5.5 大型集群(100 万在线)
设计规模
同时在线设备 100 万台,每台每分钟上报一次,消息量约 1.7 万条/秒。
| 角色 | 数量与配置 | 部署内容 |
|---|---|---|
| 接入服务器 | 2 台 8 核 16G,或云厂商网络型负载均衡 | Nginx stream + Keepalived,配置多个出口 IP;公网带宽 50M 以上 |
| Web 服务器 | 2 台 4 核 8G,硬盘 40G | Nginx、前端页面、blade-server |
| Broker 服务器 | 6 台 8 核 16G,硬盘 40G | blade-broker,JVM 堆内存 12G,单节点约 20 万连接 |
| Data 服务器 | 5 台 8 核 16G,硬盘 40G | blade-data,业务主题分区数不少于 6 |
| Kafka 服务器 | 3 台 8 核 16G,SSD 3T | Kafka 3 节点集群 |
| 数据库服务器 | 2 台 8 核 16G,SSD 500G | MySQL 主从 |
| 缓存服务器 | 6 台 4 核 8G | Redis Cluster 三主三从 |
| 时序库服务器 | 3 台 8 核 16G,每台 SSD 10T | TDengine 或 IoTDB 3 节点集群,单副本 |
6 个 broker 节点各自消费全网约 3 倍的上行消息,Kafka 集群的出口流量约 720 Mbps,分摊到 3 个节点,内网建议万兆。时序库采用 3 副本时,每个节点都保存全量数据,磁盘需按 2.4 节的合计值规划。在线设备超过 100 万时,按 5.2 节的规则继续扩展,Kafka 与时序库按消息量扩容。
部署要点
- 每个 broker 节点和 Nginx 都要按性能调优调大文件句柄数和 TCP 参数。Nginx 上每个设备连接占用 2 个句柄,
worker_rlimit_nofile与worker_connections需按连接数放大。 - 生产环境将
mqtt.server.debug设为false。发布包中application-prod.yml的默认值为true,开启后会影响性能。
配置说明
以上配置为理想情况下的测算结果,实际承载能力会因业务场景和运行环境不同而有所变化。报文大小、物模型属性数量、QoS 等级、TLS 加密、场景联动与规则转发的数量,以及网络与硬件条件,都会影响最终表现。上线前应按目标在线设备数和上报频率进行压测,重点观察 broker 节点的连接数与内存、Kafka 消费积压、时序库写入延迟和各服务器的 CPU 使用率,并以压测结果确定最终配置。
