Odoo 事件驱动库存:把 MQTT 订阅做成生产级
Odoo 事件驱动库存:把 MQTT 订阅做成生产级
Odoo 集成

Odoo 事件驱动库存:把 MQTT 订阅做成生产级

四十台固定读写器、六台手持机和两个通道门都往同一个 broker 发消息。试点能跑、工厂能跑,两者的差别不在选哪个 broker,而在事件契约、订阅进程、重复消息处理,以及凌晨三点你能否证明这条链路还活着。

11 min· By SpidersRFID Editorial Team

大多数 RFID 项目都是从「一台读写器往一个数据库写」开始,最后变成「四十台读写器更快地往同一个数据库写」。真正有意思的是这两者之间的那段路,而它几乎从来不是「你装了哪个 broker」。

为什么 MQTT 适合 RFID 事件流

RFID 资产群产生的是一条尖峰式、单向、高频的小消息流,这个形态带来几个必然结果。

  • 事件又小又密;每读一个标签就轮询一次 REST,浪费量级是三个数量级。
  • 读写器挂在不可靠的工业网络上,传输层必须容忍重连而不丢状态。
  • 发布方对消费方一无所知,而且应该保持一无所知;读写器里不能塞 ERP 逻辑。
  • 主题天生就能按站点、库区、设备分区,而这正是扩展消费者的方式。
  • MQTT 支持持久会话,重连后的订阅者能补回它错过的消息。

最后一点是团队最依赖、也最容易配错的地方。

集成的核心是契约,不是 broker

broker 是标品,事件结构才是资产,它需要和数据库表同等的纪律。

  • 从第一天就在消息体里做版本,而不是放在主题名里。
  • 固定身份字段:设备号、站点码、天线号、UTC 读取时间、EPC、RSSI,以及单调递增的序列号。
  • 定义「一次读取」到底指什么:单次天线事件,还是去重后的观测窗口。
  • 决定业务语义挂在哪一层:读写器只报事实,订阅者负责解释。
  • 把结构写成文档,并从它生成发布端与订阅端的类型。

如果两个站点对同一个事实能写出不同的字段名,你拥有的不是一套集成,而是两套恰好共用一个 broker 的集成。

订阅进程要跑在请求进程之外

最常见的生产故障是架构性的,不是技术性的:订阅逻辑被塞进了处理 Web 请求的同一个进程。

  • Odoo 的 Web worker 是短生命周期、会被回收的;长连接订阅不属于那里。
  • 用独立服务运行,有自己的进程守护、内存预算和重启策略。
  • 给它一条独立于用户连接池的数据库连接,并设定自己的语句超时。
  • 绝不允许事件处理函数在等待下一条消息时把事务挂着不提交。
  • 用与应用相同的发布流水线部署,但允许它有独立的发布节奏。

一个会在用户上传大文件时死掉的订阅进程不叫订阅进程,那叫人质。

QoS、重复消息与 retained 陷阱

服务质量等级常常按习惯选,结果是既丢事件又重复过账。

  • QoS 0 在重连时丢消息;用于遥测可以,用于库存移动不行。
  • QoS 1 保证到达,并明确允许重复;因此处理函数必须幂等。
  • QoS 2 在协议层消除重复,但要付出往返开销,在这种场景很少值得。
  • retained 用于「最后已知状态」,不能用于历史;永远不要 retained 一条库存移动。
  • 清除会话会在重连时丢掉队列;需要恢复就用持久会话,并固定一个永不变化的 client id。

选 QoS 1 加幂等处理,然后把精力花在处理函数上。

幂等、顺序与时钟纪律

关于同一个托盘的兩条事件,可能乱序到达、重复到达,或者两者都发生。

  • 幂等键由设备、EPC、天线和读取时间组成,再用唯一索引兜底。
  • 不要相信设备时钟;上报时间和接收时间都要存。
  • 乱序到达靠比较事件时间戳来纠正,而不是靠到达顺序。
  • 对于调整,写追加式事件日志再推导结存,而不是原地改数量。
  • 让重放天然安全,这样运维才敢重跑昨晚那一批。

只能靠手工纠正的库存,就是每周都要靠手工纠正的库存。

背压、批量与死信队列

在平静的周二能跟上的订阅者,会在一次全盘期间掉队。

  • 用有界刷新间隔做小批量写入,吞吐上去了,延迟又没有拖长。
  • 主动施加背压:放慢消费组,绝不允许静默丢弃。
  • 把毒消息连同原始载荷和失败原因投到死信主题。
  • 对死信增长做告警,因为静默的队列正是数据丢失藏身之处。
  • 重试要设上限并指数退避,之后把消息挂起等人工复核。

死信队列不是承认失败,它是「糟一个下午」和「账目烂掉」之间的差别。

安全与多站点租户隔离

工厂网络里一个不设防的 broker,就是任何人找到它之后都能用的库存篡改工具。

  • 在 broker 侧终止 TLS,每台设备用独立凭据,而不是一个共享密码。
  • 做主题级授权,让 A 仓的读写器无法往 B 仓的命名空间发布。
  • 载荷尽量不含个人信息;标签若映射到人,那份映射要加密或令牌化。
  • 按周期和设备退役轮换凭据,并记录每一次轮换。
  • 在数据库层把订阅者的读权限与写权限分开。

可观测性:证明链路还活着

凌晨三点的真问题从来不是「broker 还活着吗」,而是「最近一小时的读取有没有进 Odoo」。

  • 端到端跟踪消息年龄:发布时间到落库时间的差值,并设告警阈值。
  • 每台设备发心跳,营业时段内某台设备安静了就告警。
  • 统计收到、处理、去重、拒绝四个数字,并且放在一起看。
  • 保留一个对账任务,比对最近一小时的事件数与最终库存移动数。
  • 从读写器到 Odoo 记录记一个关联 id,让一条有争议的读取几分钟内可追溯。

这些都不稀奇。它只是把事件管道当成财务系统来对待的常规纪律——而当库存开始依赖它的那一刻,它就已经是财务系统了。

Odoo RFID 集成一站式方案

我们使用 Cookie 来提升您的浏览体验、分析网站流量并个性化内容。点击“接受全部”即表示您同意我们使用所有 Cookie,您也可以选择“仅必要 Cookie”。详情请参阅我们的 隐私政策 以了解更多详情。