mqtt对接嵌入式
This commit is contained in:
306
docs/mqtt-embedded-communication.md
Normal file
306
docs/mqtt-embedded-communication.md
Normal file
@@ -0,0 +1,306 @@
|
||||
# MQTT 与嵌入式通信协议
|
||||
|
||||
本文档说明后端服务与嵌入式设备之间的 MQTT Topic、通信方向、Payload 类型和 JSON 数据格式。
|
||||
|
||||
当前配置位置:
|
||||
|
||||
- 后端订阅配置:`water-admin/src/main/resources/application.yml`
|
||||
- 后端上行消息分发:`water-modules/water-app/src/main/java/org/dromara/app/mqtt`
|
||||
- 后端命令下发:`water-common/water-common-mqtt/src/main/java/org/dromara/mqtt/DeviceMqttCommandPublisher.java`
|
||||
|
||||
## 基础约定
|
||||
|
||||
| 项目 | 说明 |
|
||||
| --- | --- |
|
||||
| Broker | `mqtt.broker-url` |
|
||||
| QoS | `mqtt.qos`,当前默认 `1` |
|
||||
| 设备编号 | Topic 第一段 `{deviceNo}` |
|
||||
| Topic 变量 | 文档中的 `{deviceNo}` 替换为真实设备编号,例如 `/01/publish/register` |
|
||||
| JSON 编码 | UTF-8 |
|
||||
| 时间格式 | `yyyy-MM-dd HH:mm:ss` |
|
||||
|
||||
后端会订阅以下 Topic:
|
||||
|
||||
```yaml
|
||||
- /+/publish/finish/schedule
|
||||
- /+/publish/register
|
||||
- /+/publish/power
|
||||
- /+/publish/ack
|
||||
- /+/publish/finish/key
|
||||
- /+/publish/error
|
||||
- /+/subscriber/cmd
|
||||
```
|
||||
|
||||
## Topic 总览
|
||||
|
||||
| 功能名称 | 通信方向 | 订阅名称 / Topic | Payload 类型 | 后端处理 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 排程任务完成上报 | 设备发布,后端订阅 | `/{deviceNo}/publish/finish/schedule` | JSON | 当前记录日志 |
|
||||
| 设备注册 | 设备发布,后端订阅 | `/{deviceNo}/publish/register` | JSON | 注册或更新设备 |
|
||||
| 电量上报 | 设备发布,后端订阅 | `/{deviceNo}/publish/power` | JSON | 更新设备电量 |
|
||||
| 命令应答 ACK | 设备发布,后端订阅 | `/{deviceNo}/publish/ack` | JSON 或纯文本 | 清理待确认命令 |
|
||||
| 按键浇水完成上报 | 设备发布,后端订阅 | `/{deviceNo}/publish/finish/key` | JSON | 当前记录日志 |
|
||||
| 硬件故障上报 | 设备发布,后端订阅 | `/{deviceNo}/publish/error` | JSON | 当前记录日志 |
|
||||
| 下发命令 | 后端发布,设备订阅 | `/{deviceNo}/subscriber/cmd` | JSON | 设备执行命令 |
|
||||
|
||||
## 设备注册
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 功能名称 | 设备注册 |
|
||||
| 通信方向 | 设备发布,后端订阅 |
|
||||
| Topic | `/{deviceNo}/publish/register` |
|
||||
| Payload 类型 | JSON |
|
||||
|
||||
后端以 Topic 中的 `{deviceNo}` 作为设备编号,payload 中的 `deviceNo` 即使传入也会被 Topic 覆盖。
|
||||
|
||||
示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"deviceName": "一号浇水设备",
|
||||
"status": "1",
|
||||
"workStatus": "0",
|
||||
"powerLevel": "86",
|
||||
"wifiName": "office-wifi",
|
||||
"deviceEm": "WATER-EM-01",
|
||||
"deviceSn": "SN202606100001",
|
||||
"fwVer": "1.0.0",
|
||||
"macAddress": "AA:BB:CC:DD:EE:FF",
|
||||
"bindToken": "123456"
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| deviceName | string | 否 | 设备名称 |
|
||||
| status | string | 否 | 设备状态:`1` 在线,`0` 离线,`2` 到期,`3` 故障;为空时后端默认 `2` |
|
||||
| workStatus | string | 否 | 工作状态:`0` 休息,`1` 工作 |
|
||||
| powerLevel | string | 否 | 电量 |
|
||||
| wifiName | string | 否 | WiFi 名称 |
|
||||
| deviceEm | string | 否 | 设备型号 |
|
||||
| deviceSn | string | 否 | 设备序列号 |
|
||||
| fwVer | string | 否 | 固件版本 |
|
||||
| macAddress | string | 否 | MAC 地址 |
|
||||
| bindToken | string | 否 | 设备绑定令牌 |
|
||||
|
||||
## 电量上报
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 功能名称 | 电量上报 |
|
||||
| 通信方向 | 设备发布,后端订阅 |
|
||||
| Topic | `/{deviceNo}/publish/power` |
|
||||
| Payload 类型 | JSON |
|
||||
|
||||
示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"powerLevel": "86"
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| powerLevel | string | 是 | 电量值,后端当前按字符串保存 |
|
||||
|
||||
## 命令应答 ACK
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 功能名称 | 命令应答 |
|
||||
| 通信方向 | 设备发布,后端订阅 |
|
||||
| Topic | `/{deviceNo}/publish/ack` |
|
||||
| Payload 类型 | JSON,兼容纯文本 |
|
||||
|
||||
推荐 JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"commandId": "9f4f1f2e8c6a4e1f8b7f3a1d2c0b9e11",
|
||||
"status": "1",
|
||||
"message": "receive"
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| commandId | string | 是 | 后端下发命令时携带的命令 ID,用于清理待 ACK 命令 |
|
||||
| status | string | 否 | 执行状态,建议 `1` 成功,`0` 失败 |
|
||||
| message | string | 否 | 设备返回消息 |
|
||||
|
||||
兼容格式:
|
||||
|
||||
```text
|
||||
receive
|
||||
```
|
||||
|
||||
说明:如果设备只返回纯文本,例如 `receive`,后端会查找该设备当前待确认命令。若只有一条 pending 命令,则按该命令完成 ACK;若没有或有多条 pending 命令,只记录日志,不清理命令。嵌入式侧建议优先使用 JSON ACK,并回传 `commandId`。
|
||||
|
||||
## 下发命令
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 功能名称 | 下发命令 |
|
||||
| 通信方向 | 后端发布,设备订阅 |
|
||||
| Topic | `/{deviceNo}/subscriber/cmd` |
|
||||
| Payload 类型 | JSON |
|
||||
|
||||
后端下发手动开关设备命令示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"deviceNo": "01",
|
||||
"workStatus": "1",
|
||||
"startTime": "2026-06-10 14:35:31",
|
||||
"durationMin": 20,
|
||||
"commandId": "9f4f1f2e8c6a4e1f8b7f3a1d2c0b9e11",
|
||||
"commandType": "switchDevice"
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| deviceNo | string | 是 | 设备编号 |
|
||||
| workStatus | string | 是 | `0` 关闭浇水,`1` 开始浇水 |
|
||||
| startTime | string | 否 | 开始时间,格式 `yyyy-MM-dd HH:mm:ss` |
|
||||
| durationMin | number | 是 | 持续时间,单位分钟,必须大于 0 |
|
||||
| commandId | string | 是 | 后端自动生成,设备 ACK 必须原样返回 |
|
||||
| commandType | string | 是 | 命令类型,手动开关设备为 `switchDevice` |
|
||||
|
||||
设备收到命令后,应发布 ACK 到:
|
||||
|
||||
```text
|
||||
/{deviceNo}/publish/ack
|
||||
```
|
||||
|
||||
推荐 ACK:
|
||||
|
||||
```json
|
||||
{
|
||||
"commandId": "9f4f1f2e8c6a4e1f8b7f3a1d2c0b9e11",
|
||||
"status": "1",
|
||||
"message": "receive"
|
||||
}
|
||||
```
|
||||
|
||||
## 排程任务完成上报
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 功能名称 | 排程任务完成上报 |
|
||||
| 通信方向 | 设备发布,后端订阅 |
|
||||
| Topic | `/{deviceNo}/publish/finish/schedule` |
|
||||
| Payload 类型 | JSON |
|
||||
| 当前后端行为 | 写入浇水记录 |
|
||||
|
||||
JSON 示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"deviceNo": "dcda0cfa289c",
|
||||
"startWeek": 5,
|
||||
"startTime": "2026-06-05 14:37",
|
||||
"durationMin": 3,
|
||||
"triggerType": "mqtt on"
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| deviceNo | string | 否 | 设备编号;后端以 Topic 中的 `{deviceNo}` 为准,不一致时记录 warn |
|
||||
| startWeek | number | 否 | 星期几,`1` 到 `7`;当前后端不入库 |
|
||||
| startTime | string | 是 | 开始时间,支持 `yyyy-MM-dd HH:mm:ss` 或 `yyyy-MM-dd HH:mm` |
|
||||
| endTime | string | 否 | 结束时间,支持 `yyyy-MM-dd HH:mm:ss` 或 `yyyy-MM-dd HH:mm` |
|
||||
| durationMin | number | 否 | 预计持续时间,单位分钟;大于 `0` 时后端按 `startTime + durationMin` 计算预计结束时间 |
|
||||
| triggerType | string | 否 | 设备触发来源;当前后端忽略该字段,排程完成记录固定入库为 `0` |
|
||||
| scheduleId | number | 否 | 后端忽略 payload 中的该字段,按 `AppSchedulingDevice.deviceNo` 查询排程 ID;查不到时写入 `0` |
|
||||
|
||||
后端先计算预计结束时间:`durationMin > 0` 时使用 `startTime + durationMin`,否则使用 payload 中的 `endTime`。实际入库的 `endTime` 取“消息接收时间”和“预计结束时间”中较早的时间,`durationMin` 按 `startTime` 到实际入库 `endTime` 重新计算。
|
||||
|
||||
## 按键浇水完成上报
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 功能名称 | 按键浇水完成上报 |
|
||||
| 通信方向 | 设备发布,后端订阅 |
|
||||
| Topic | `/{deviceNo}/publish/finish/key` |
|
||||
| Payload 类型 | JSON |
|
||||
| 当前后端行为 | 写入浇水记录 |
|
||||
|
||||
JSON 示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"deviceNo": "dcda0cfa289c",
|
||||
"startWeek": 5,
|
||||
"startTime": "2026-06-05 17:43",
|
||||
"durationMin": 0,
|
||||
"triggerType": "key"
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| deviceNo | string | 否 | 设备编号;后端以 Topic 中的 `{deviceNo}` 为准,不一致时记录 warn |
|
||||
| startWeek | number | 否 | 星期几,`1` 到 `7`;当前后端不入库 |
|
||||
| startTime | string | 是 | 开始时间,支持 `yyyy-MM-dd HH:mm:ss` 或 `yyyy-MM-dd HH:mm` |
|
||||
| endTime | string | 否 | 结束时间,支持 `yyyy-MM-dd HH:mm:ss` 或 `yyyy-MM-dd HH:mm` |
|
||||
| durationMin | number | 否 | 预计持续时间,单位分钟;大于 `0` 时后端按 `startTime + durationMin` 计算预计结束时间 |
|
||||
| triggerType | string | 否 | 设备触发来源;当前后端忽略该字段,按键完成记录固定入库为 `1` |
|
||||
|
||||
后端先计算预计结束时间:`durationMin > 0` 时使用 `startTime + durationMin`,否则使用 payload 中的 `endTime`。实际入库的 `endTime` 取“消息接收时间”和“预计结束时间”中较早的时间,`durationMin` 按 `startTime` 到实际入库 `endTime` 重新计算。按键完成记录的 `scheduleId` 固定为 `0`。
|
||||
|
||||
## 硬件故障上报
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 功能名称 | 硬件故障上报 |
|
||||
| 通信方向 | 设备发布,后端订阅 |
|
||||
| Topic | `/{deviceNo}/publish/error` |
|
||||
| Payload 类型 | JSON |
|
||||
| 当前后端行为 | 记录日志,暂未入库 |
|
||||
|
||||
建议 JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"errorCode": "E001",
|
||||
"errorType": "pump",
|
||||
"message": "pump blocked",
|
||||
"level": "error",
|
||||
"time": "2026-06-10 10:00:00"
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| errorCode | string | 建议 | 故障编码 |
|
||||
| errorType | string | 否 | 故障类型 |
|
||||
| message | string | 建议 | 故障描述 |
|
||||
| level | string | 否 | 故障级别,例如 `warn`、`error` |
|
||||
| time | string | 否 | 故障发生时间 |
|
||||
|
||||
## 嵌入式侧实现要点
|
||||
|
||||
1. 设备启动后发布注册消息到 `/{deviceNo}/publish/register`。
|
||||
2. 设备定时或电量变化时发布电量到 `/{deviceNo}/publish/power`。
|
||||
3. 设备订阅自己的命令 Topic:`/{deviceNo}/subscriber/cmd`。
|
||||
4. 设备收到命令后立即返回 ACK 到 `/{deviceNo}/publish/ack`,推荐返回 JSON 并携带 `commandId`。
|
||||
5. 排程或按键浇水完成后,分别发布到 `/{deviceNo}/publish/finish/schedule` 或 `/{deviceNo}/publish/finish/key`。
|
||||
6. 硬件异常时发布到 `/{deviceNo}/publish/error`。
|
||||
199
docs/project-architecture.md
Normal file
199
docs/project-architecture.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# Water 项目架构图
|
||||
|
||||
本文档按当前项目代码结构整理,重点包含后端模块、智能灌溉业务、MQTT 设备通信、ACK 应答与重发链路。
|
||||
|
||||
## 整体模块
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
APP["移动端 / 管理端 App"]
|
||||
DEVICE["灌溉设备"]
|
||||
BROKER["MQTT Broker<br/>TLS: ssl://service.reinkun.com:8883"]
|
||||
|
||||
subgraph BACKEND["water 后端服务"]
|
||||
ADMIN["water-admin<br/>Spring Boot 启动入口"]
|
||||
APPMOD["water-modules/water-app<br/>设备、排程、浇水记录、MQTT业务分发"]
|
||||
SYSTEM["water-modules/water-system<br/>用户、角色、租户、权限"]
|
||||
COMMON["water-common<br/>通用能力"]
|
||||
MQTT["water-common-mqtt<br/>MQTT连接、TLS、订阅、发布、ACK重发"]
|
||||
REDISCOMMON["water-common-redis<br/>Redis 工具与 Redisson"]
|
||||
DBACCESS["water-common-mybatis<br/>MyBatis Plus / 数据权限"]
|
||||
end
|
||||
|
||||
MYSQL[("MySQL<br/>业务数据")]
|
||||
REDIS[("Redis<br/>缓存、设备状态、待ACK命令")]
|
||||
|
||||
APP -->|"HTTP REST"| ADMIN
|
||||
ADMIN --> APPMOD
|
||||
ADMIN --> SYSTEM
|
||||
ADMIN --> COMMON
|
||||
APPMOD --> DBACCESS
|
||||
SYSTEM --> DBACCESS
|
||||
DBACCESS --> MYSQL
|
||||
APPMOD --> REDISCOMMON
|
||||
MQTT --> REDISCOMMON
|
||||
REDISCOMMON --> REDIS
|
||||
MQTT <-->|"MQTT over TLS"| BROKER
|
||||
DEVICE <-->|"MQTT over TLS"| BROKER
|
||||
MQTT --> APPMOD
|
||||
```
|
||||
|
||||
## 后端分层
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
HTTP["HTTP 请求<br/>/app/v1/**"]
|
||||
CONTROLLER["AppController<br/>设备、排程、日志、用户接口"]
|
||||
SERVICE["Service 层<br/>IAppDeviceService / IAppScheduleService / IAppWateringLogService"]
|
||||
MAPPER["Mapper 层<br/>MyBatis Plus Mapper"]
|
||||
DB[("MySQL")]
|
||||
|
||||
HTTP --> CONTROLLER
|
||||
CONTROLLER --> SERVICE
|
||||
SERVICE --> MAPPER
|
||||
MAPPER --> DB
|
||||
|
||||
CONTROLLER --> CMDPUB["IDeviceCommandPublisher<br/>设备命令发布接口"]
|
||||
CMDPUB --> MQTTIMPL["DeviceMqttCommandPublisher<br/>MQTT命令实现"]
|
||||
```
|
||||
|
||||
## MQTT 高并发消费链路
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
DEVICE1["设备 A"]
|
||||
DEVICE2["设备 B"]
|
||||
DEVICEN["设备 N"]
|
||||
BROKER["MQTT Broker"]
|
||||
CLIENT["MqttAsyncClient<br/>单个后端订阅客户端"]
|
||||
QUEUE["有界内存队列<br/>queue-capacity: 20000"]
|
||||
CONSUMERS["mqtt-consumer-*<br/>consumer-count: 16<br/>batch-size: 100"]
|
||||
DISPATCHER["MqttMessageDispatcher<br/>topic 路由"]
|
||||
|
||||
DATA["DeviceDataHandler<br/>/water/{deviceNo}/data"]
|
||||
STATUS["DeviceStatusHandler<br/>/water/{deviceNo}/status"]
|
||||
ERROR["ErromesHandler<br/>/water/{deviceNo}/erromes"]
|
||||
ACK["IDeviceCommandAckHandler<br/>/water/{deviceNo}/ack"]
|
||||
|
||||
DEVICE1 --> BROKER
|
||||
DEVICE2 --> BROKER
|
||||
DEVICEN --> BROKER
|
||||
BROKER --> CLIENT
|
||||
CLIENT -->|"快速入队"| QUEUE
|
||||
QUEUE -->|"批量拉取"| CONSUMERS
|
||||
CONSUMERS --> DISPATCHER
|
||||
DISPATCHER --> DATA
|
||||
DISPATCHER --> STATUS
|
||||
DISPATCHER --> ERROR
|
||||
DISPATCHER --> ACK
|
||||
```
|
||||
|
||||
## 设备命令 ACK 与重发
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as 移动端 App
|
||||
participant API as AppController
|
||||
participant Pub as DeviceMqttCommandPublisher
|
||||
participant Redis as Redis
|
||||
participant MQTT as MqttClientManager
|
||||
participant Broker as MQTT Broker
|
||||
participant Dev as 设备
|
||||
participant Ack as MqttCommandAckService
|
||||
participant Retry as MqttCommandRetryTask
|
||||
|
||||
App->>API: switchDevice(workStatus, durationMin)
|
||||
API->>Pub: send(DeviceCommand)
|
||||
Pub->>Redis: 保存 pending commandId
|
||||
Pub->>MQTT: publish /water/{deviceNo}/command
|
||||
MQTT->>Broker: 下发命令
|
||||
Broker->>Dev: 命令到达设备
|
||||
|
||||
alt 设备正常回复
|
||||
Dev->>Broker: publish /water/{deviceNo}/ack
|
||||
Broker->>MQTT: ACK 消息
|
||||
MQTT->>Ack: handleAck(deviceNo, payload)
|
||||
Ack->>Redis: 删除 pending,保存 ack 结果
|
||||
else 设备断网或未回复
|
||||
Retry->>Redis: 扫描 pending 命令
|
||||
Retry->>Redis: 检查设备状态缓存
|
||||
alt 设备在线且未超过重试次数
|
||||
Retry->>MQTT: 重新 publish 命令
|
||||
MQTT->>Broker: 重新下发
|
||||
else 设备离线
|
||||
Retry->>Redis: 延后 nextRetryAt
|
||||
else 超过最大重试次数
|
||||
Retry->>Redis: 删除 pending
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Redis Key 规划
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
REDIS[("Redis")]
|
||||
STATUS["mqtt:device:status:{deviceNo}<br/>设备最新在线状态<br/>TTL: 300s"]
|
||||
PENDING["mqtt:command:pending:{commandId}<br/>待ACK命令详情<br/>TTL: 86400s"]
|
||||
PENDING_IDS["mqtt:command:pending:ids<br/>待ACK commandId 集合"]
|
||||
ACK["mqtt:command:ack:{commandId}<br/>设备ACK结果<br/>TTL: 86400s"]
|
||||
|
||||
REDIS --> STATUS
|
||||
REDIS --> PENDING
|
||||
REDIS --> PENDING_IDS
|
||||
REDIS --> ACK
|
||||
```
|
||||
|
||||
## 核心 Topic 约定
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
DEVICE["设备"]
|
||||
SERVER["后端"]
|
||||
|
||||
DEVICE -->|"/water/{deviceNo}/data"| SERVER
|
||||
DEVICE -->|"/water/{deviceNo}/status"| SERVER
|
||||
DEVICE -->|"/water/{deviceNo}/erromes"| SERVER
|
||||
DEVICE -->|"/water/{deviceNo}/ack"| SERVER
|
||||
SERVER -->|"/water/{deviceNo}/command"| DEVICE
|
||||
```
|
||||
|
||||
设备 ACK 示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"commandId": "后端下发的commandId",
|
||||
"status": "success",
|
||||
"message": "ok"
|
||||
}
|
||||
```
|
||||
|
||||
## 高并发关注点
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
A["上千设备并发连接"] --> B["MQTT Broker 承载连接数和 TLS 握手"]
|
||||
B --> C["后端单/少量订阅客户端消费通配 topic"]
|
||||
C --> D["有界队列吸收突发流量"]
|
||||
D --> E["批量消费降低线程调度成本"]
|
||||
E --> F["状态写 Redis,避免心跳打数据库"]
|
||||
F --> G["数据/告警后续建议批量落库"]
|
||||
```
|
||||
|
||||
当前已完成的关键优化:
|
||||
|
||||
- MQTT 使用 `MqttAsyncClient`
|
||||
- MQTT 连接支持 TLS
|
||||
- MQTT 回调只入队,不直接执行业务
|
||||
- 消息按批次消费
|
||||
- 设备状态写 Redis 缓存
|
||||
- 设备命令支持 ACK
|
||||
- 未 ACK 命令支持离线延后和超时重发
|
||||
- 日志异步队列已扩大
|
||||
|
||||
后续建议:
|
||||
|
||||
- 设备数据和告警数据落库改为批量写入
|
||||
- 对设备命令增加业务状态表,便于前端查询命令执行状态
|
||||
- MQTT Broker 使用集群或至少做连接数、会话数、消息速率监控
|
||||
- 生产环境 TLS 不建议开启 `skip-verify`
|
||||
Reference in New Issue
Block a user