如何基于 MQTT 触发边缘同步?

解读

面试官真正想考察的是:在国内边缘节点资源受限、网络抖动大、离线优先的场景下,你能否把 MQTT 的“轻量发布/订阅”与 CouchDB 的“多主复制”无缝衔接,做到实时、可靠、可回滚的触发同步,而不是简单“调一下 API”。
关键词:触发时机、断点续传、QoS 映射、双向回环避免、国密合规

知识点

  1. CouchDB 复制模型_changes 顺序日志、since=now 增量、doc_ids 过滤、selector 过滤、retry=true 断点续传。
  2. MQTT 语义:QoS0/1/2、 retained 消息、共享订阅($share/{group}/topic)、遗嘱消息。
  3. 边缘侧架构:MQTT Broker(EMQX/ mosquitto)+ 本地 CouchDB 节点 + 轻量规则引擎(Node-RED/ Lua/ Go 二进制 <30 MB)。
  4. 触发策略
    • 事件触发:MQTT 消息体携带 last_seq,边缘节点用 since=last_seq 拉增量。
    • 心跳触发:Broker 每 30 s 广播 ping/{siteId},边缘收到后对比本地 update_seq 与云端 update_seq,差值超阈值即启动同步。
  5. 一致性保障
    • 幂等写入:CouchDB _rev 天然幂等,重复推送同版本文档不会冲突。
    • 回环避免:在 MQTT 消息头注入 couchdb-replicated: true,边缘节点收到后不再回写,防止“乒乓”同步。
  6. 国密合规:TLS 通道改用 SM2 双证、MQTT 密码字段做 SM4 加密,满足等保 2.0 三级传输保密要求。
  7. 降级方案:MQTT 断网 >5 min 自动切换本地定时轮询_changes?timeout=20000&heartbeat=10000),网络恢复后再切回 MQTT 触发,保证离线优先体验。

答案

给出一套可直接落地的“三件套”方案,面试时按“场景→痛点→设计→验证”四步回答即可。

第一步:场景抽象
国内连锁零售边缘门店,每个店部署树莓派 4B(2 GB RAM),运行 CouchDB 3.3 + EMQX Edge,4G 链路月流量 <1 GB,需把 POS 订单实时同步到总部。

第二步:触发链路

  1. 总部 CouchDB 写订单 → 触发 Lua 脚本 → 向 MQTT 主题 orders/{shopId} 发布 retained 消息,Payload 为 {“last_seq”: 12345, “shopId”: “SH001”},QoS=1。
  2. 边缘节点订阅 orders/SH001,收到消息后调用
    curl -X POST http://localhost:5984/_replicate -d '{"source":"https://总部域名/orders","target":"orders","since":12345,"retry":true,"selector":{"shopId":"SH001"}}' -H "Content-Type:application/json"
    利用selector 过滤只拉取本店数据,流量降低 95%。
  3. 同步完成后,边缘节点向 ack/SH001 发布 {“last_seq”: 新值},总部收到后更新同步水位,形成闭环确认

第三步:异常处理

  • 网络抖动:EMQX 的 QoS1 重传 + CouchDB retry=true 断点续传,保证至少一次且不丢序。
  • 回环抑制:边缘回写总部时,在文档里加字段 fromEdge: true,总部过滤器 selector: {"fromEdge":{"$exists":false}},天然屏蔽回环。
  • 流量尖峰:MQTT 消息体只传 last_seq(8 B),不传全量文档,100 万条订单 < 8 MB 流量

第四步:效果验证
压测 100 个边缘节点,总部 8 核 16 G,单节点 TPS 2500,端到端延迟 P99 < 3 s,4G 流量节省 92%,完全满足国内运营商套餐限制

拓展思考

  1. Serverless 化:把 Lua 脚本换成阿里云函数计算 FC,通过 MQTT 规则引擎直接触发 FC,复制任务由 FC 托管,边缘零代码,适合OT 人员不会写脚本的场合。
  2. 双向同步冲突策略:若边缘也产生订单,可用时间戳+UUID 复合键_id,冲突时总部以最新时间戳为准,并通过 MQTT 推送 conflict/resolution 主题,边缘自动更新本地视图,保证财务一致性
  3. 边缘 AI 预处理:在 MQTT 消息里携带 predict_reorder: true,边缘节点同步前先写本地 AI 模型,预测是否需要补货,再把预测结果作为附件写入 CouchDB,实现AI+数据库一体化,面试可展示“业务增值”思维。