IoT 项目的难点不在“显示几个设备数据”,而在设备数量增加后,数据是否稳定上传、断线是否可恢复、告警是否及时、历史曲线是否可查询、客户看到的数据是否可信。架构要从采集链路开始设计。
典型架构链路
- 设备 / 网关
- MQTT / HTTP 上报
- 接入服务
- 消息队列
- 规则引擎 / 告警服务
- 时序数据 + 业务数据库
- 看板 / 小程序 / 客户端
设备接入:先定义协议和身份
设备需要有唯一 ID、密钥、型号、固件版本和所属客户。接入层要校验身份,避免任意设备写入数据。
采集协议:MQTT 和 HTTP 适合不同场景
高频、长连接、低功耗设备常用 MQTT;低频上报或简单网关可以用 HTTP。关键是定义稳定的数据格式、时间戳和错误重试机制。
消息队列:削峰和解耦很重要
设备数据可能突然集中上报,直接写数据库容易把服务打满。消息队列可以把接入、解析、存储、告警分开,提高系统韧性。
时序数据:历史曲线不能只靠普通业务表
温度、压力、电量、运行状态等连续数据适合按时间维度存储。要提前设计采样频率、保留周期、聚合粒度和查询索引。
告警规则:实时性和误报都要考虑
告警规则不仅是超过阈值,还包括连续 N 次异常、离线时长、恢复通知、告警升级和通知去重。
可视化看板:不同角色看不同粒度
运维看设备健康,客户看运行状态,管理者看统计趋势。数据权限和展示层级需要和业务角色绑定。
脱敏项目复盘:设备数据平台从采集到工单闭环
IoT 项目常从“大屏能看到曲线”开始,但业务价值来自设备异常被发现、确认、派单和恢复。现场网络不稳定、协议版本不一致、设备时间漂移,如果只追求接入数量,最终会得到一套数据很多却无法信任的展示系统。
业务与产品形态
第一阶段选择影响生产的关键设备,定义在线状态、运行参数、报警等级和处置责任。产品包括值班大屏、工程师报警工作台、设备详情与趋势、工单处理页,以及面向客户的只读门户。大屏负责发现,工作台负责行动,详情页负责判断,不能让所有信息都挤在一张图上。
技术解决方案
边缘网关完成协议适配、断网缓存和基础校验,通过 MQTT 上传带设备号、采集时间、序列号和质量标识的消息。接入层校验签名并写入队列,消费端按设备与序列号幂等;时序数据进入时序存储,设备档案、规则、报警和工单进入关系数据库。冷热数据分层,聚合曲线预计算,避免每次打开页面扫描原始点位。
难点设计
设备时间、平台接收时间和入库时间必须分开保存,才能识别时钟漂移与网络延迟。报警规则要包含持续时间、恢复条件、抑制窗口和维护模式,避免一个抖动点位制造报警风暴。设备离线、重复上报、乱序和补传都要有确定处理策略,数据质量差时界面必须显示“不可信”,不能画出一条看似连续的假曲线。
用户体验
报警卡片同时显示设备、位置、当前值、阈值、持续时间、关联曲线和操作手册,工程师可以确认、转派、备注或创建工单。相同根因的报警合并展示,恢复后保留处置时间线。手机端优先支持确认与拍照,复杂规则配置留在后台完成。
产品效果与验收
先用模拟器和现场回放验证断网、补传、乱序和高频报警,再选少量设备灰度。指标包括采集完整率、时间偏差、重复率、报警准确率、平均确认时间、平均恢复时间和无效报警占比。平台是否有效,不看接入了多少点位,而看异常是否更早暴露、责任是否更快到人、处置是否留下证据。
设备规模上来以后,问题会从“能接入”变成“能治理”
IoT 平台最初接十台设备时,直接把 JSON 写入数据库也能工作;设备数量、上报频率和固件版本增加后,乱序、重复、离线补传、字段变化和告警风暴会同时出现。设计时要先定义设备身份、消息主题、数据版本和时间语义,再决定传输与存储。否则平台收到的只是大量无法解释的数据。
设备身份和密钥要支持生命周期管理
每台设备应有唯一标识和独立凭据,生产、测试设备不能共用密钥。设备首次激活、密钥轮换、停用和转移客户都要有后台流程。服务端除了验证连接,还要校验设备是否有权发布对应主题。凭据泄露后能够只吊销单台设备,而不是更换整批设备配置。
消息处理必须接受重复和乱序
MQTT 的 QoS 不能替代业务幂等。网络抖动和网关重连仍可能产生重复消息,离线缓存又会让旧数据晚到。消息中需要设备时间、网关接收时间、序列号和协议版本;消费端以设备与序列号去重,并根据业务决定是否接受迟到数据。控制指令还要有指令 ID、过期时间、确认和超时状态,不能只看“消息发送成功”。
冷热数据分层能控制成本
最近几天的高频数据用于实时看板和告警,可以保存在时序库或按时间分区的热表;长期历史用于趋势分析,应降采样或归档到更便宜的存储。设备基础信息、客户、规则和工单仍属于关系型业务数据。把所有内容塞进一张大表,既影响查询,也很难设置不同的保留周期。
告警需要抑制、聚合和恢复机制
温度连续越界一分钟,不应该每秒生成一条告警。规则引擎需要持续时间、恢复阈值、静默窗口、设备分组和通知升级。设备大面积离线时先判断网关或网络故障,避免给每台设备创建工单。每条告警要保留触发数据、规则版本、确认人、处理过程和恢复时间,才能分析误报率和平均修复时间。
设备数据链路的接口和数据表要怎样落地
每台设备先有可信身份,再允许发布数据
设备注册表保存 device_id、型号、固件版本、所属租户、启停状态和密钥版本。MQTT 场景按设备限制 topic 发布与订阅权限,HTTP 场景使用可轮换的令牌或设备证书,不能让所有终端共享一个长期密钥。设备报废、转移和密钥泄露都要能单独吊销,不影响同批次其他设备。
采集消息要保留设备时间与平台接收时间
统一数据包至少包含 device_id、sequence、event_time、received_at、schema_version 和 metrics。sequence 用于识别重复与缺包,双时间戳用于判断设备时钟漂移和网络延迟。解析服务按 schema_version 选择解码器,原始报文短期保留,遇到协议升级或解析错误时可以重放,而不是要求现场重新采集。
乱序、补传和海量历史数据要分开处理
消息队列按 device_id 分区,在可接受时间窗口内重排;超过窗口的迟到数据写入历史但不随意改写已经触发的业务动作。高频明细进入时序存储,近期热点保留高精度,长期数据按分钟或小时降采样并进入冷存储。设备档案、规则和租户关系仍放关系数据库,避免把所有数据硬塞进一种数据库。
告警不是一条 if 语句,而是一套状态机
阈值判断要配置持续时间、回差、抑制窗口和恢复条件,状态至少包括 pending、firing、acknowledged、resolved。否则温度在临界值附近抖动会连续发送几十条通知。下行控制命令还要保存 command_id、发送时间、设备确认和超时状态,平台显示“已下发”与“设备已执行”必须是两个不同结果。
落地前建议确认
- 设备是否有唯一身份和密钥
- 数据上报频率是多少
- 是否需要离线和异常告警
- 历史数据需要保留多久
