第十部分:当前实现说明

10.1 技术基线

层当前实现职责
管理后台Vue 3、TypeScript、Vite、Pinia、Vue Router管理员和运维操作界面
用户端原生微信小程序用户登录、设备绑定、查看和控制
后端Java 17、Spring Boot 3.3、Spring Security、Spring Data JPA模块化单体业务 API
业务数据库MySQL + Flyway用户、产品、设备、绑定、指令、告警和审计
登录与缓存Redis不透明登录 Token 验证、产品等热点缓存
设备消息Kafka后端唯一的设备消息订阅/发布入口
MQTTEMQX设备连接、ACL、MQTT Topic 与 Kafka 双向桥接

后端不引入 MQTT Client,也不直接订阅 EMQX。EMQX 负责 MQTT 会话,EMQX 规则/Bridge 将上行消息写入 Kafka;后端消费 Kafka。下行控制由后端写 Kafka,再由 EMQX Bridge 投递 MQTT。

10.2 工程结构

iot-platform-mvp/
├─ admin-web/                 Vue 3 + TypeScript 管理后台
│  ├─ src/api                API 封装
│  ├─ src/stores             登录状态
│  ├─ src/router             路由与角色守卫
│  ├─ src/layouts            后台布局
│  └─ src/views              总览、产品、设备、用户、指令、告警、审计
├─ backend/                   Spring Boot 单体
│  ├─ src/main/java/.../api  REST Controller 与统一响应
│  ├─ config                 Security、Redis Cache、种子数据
│  ├─ domain/repository      JPA 实体与仓储
│  ├─ service                认证和设备业务用例
│  ├─ messaging              Kafka 生产者/消费者及消息 DTO
│  └─ resources/db/migration Flyway MySQL 结构
└─ mini-program/              原生微信小程序

10.3 单体模块边界

当前一个 Jar 内保留以下逻辑模块:

  • IAM:后台账号、小程序账号、Redis 登录会话、RBAC。
  • 产品/物模型:产品、协议和物模型版本。
  • 设备:设备身份、绑定、在线状态、当前属性和遥测。
  • 控制:指令入库、Kafka 下行、ACK 状态回写。
  • 告警:设备事件转告警、告警处置。
  • 审计:关键管理与用户操作留痕。

模块通过服务接口和 Kafka 事件 DTO 组织,不在首期过早拆分独立进程。

10.4 Kafka 与 EMQX 数据流

设备属性/事件
  → MQTT Topic
  → EMQX Rule/Bridge
  → iot.device.telemetry.up / iot.device.event.up
  → KafkaInboundListener
  → DeviceService
  → MySQL + Redis Cache

管理后台/小程序控制
  → Spring Boot API
  → device_command(PENDING)
  → iot.device.command.down
  → EMQX Bridge
  → MQTT 指令 Topic
  → 设备 ACK
  → iot.device.command.ack
  → device_command(SUCCEEDED/FAILED)

Topic 的 Key 统一为 deviceId,以保证单设备消息分区内有序。上行使用 messageId 幂等;下行使用 commandId 关联 ACK。

10.5 Redis 使用

  1. 后台或小程序登录成功后生成高熵不透明 Token。
  2. 会话写入 iot:session:{token},Value 保存用户 ID、用户名和角色,TTL 默认 24 小时。
  3. 每次 Bearer 请求由 TokenAuthenticationFilter 查询 Redis 并恢复 Spring Security 身份。
  4. 产品列表使用 Spring Cache + Redis,默认 TTL 10 分钟;产品创建时清除缓存。
  5. 测试 profile 使用内存 SessionStore 和 Simple Cache,不访问真实 Redis。

后续可将设备在线 TTL、验证码限流、接口幂等键和短时设备影子热点加入 Redis,但业务事实仍以 MySQL/Kafka 为准。

10.6 MySQL 使用

当前 Flyway V1__init_schema.sql 创建:iam_user、iot_product、iot_device、device_telemetry、device_command、device_alert、audit_log。设备表使用乐观锁版本字段;遥测以 (device_id,message_id) 唯一约束去重。

初期遥测可保存在 MySQL 便于完成闭环。数据量达到容量阈值后,把遥测存储模块替换为专用时序方案,其他业务表仍留在 MySQL。

10.7 配置与启动

中间件地址不写入源码。字段清单见 backend/.env.example;收到实际地址文档后映射为部署环境变量。

# 后端测试与启动
cd iot-platform-mvp\backend
.\mvnw.cmd test
.\mvnw.cmd spring-boot:run

# 管理后台
cd ..\admin-web
npm install
npm run dev
  • Spring Boot:http://127.0.0.1:8080
  • Vue 开发服务:http://127.0.0.1:5173
  • 小程序开发地址:http://127.0.0.1:8080

10.8 测试与部署边界

自动测试使用 H2、内存登录会话和 Noop Kafka Publisher,验证单体业务、权限、绑定、遥测事件和指令状态,不依赖已部署中间件。收到地址与认证信息后还需执行 MySQL 迁移验证、Redis TTL/故障验证、Kafka Topic ACL 与收发验证、EMQX 双向 Bridge 验证和真实设备 ACK 联调。

10.9 微服务演进

满足以下任一条件再拆分:模块需要独立扩缩容、发布节奏明显不同、数据所有权稳定、单体发布影响无法接受。建议顺序:

  1. 先拆 device-ingestion(Kafka 上行、遥测、在线态),因为吞吐模型最不同。
  2. 再拆 device-command(指令、ACK、超时、Outbox)。
  3. 再按业务量拆 alert-service 和 iam-service。
  4. 产品/物模型与核心设备资产在边界稳定前保留一起。

拆分前先补 Transactional Outbox、契约测试、事件版本、可观测性和数据库归属,不以“类多了”作为拆服务理由。