一次工业 IoT 项目的架构思考:业务和架构的边界在哪里

0 阅读6分钟

为什么"工位"不应该出现在 IoT 架构里

一次工业 IoT 项目的架构复盘:当业务和技术混在一起的时候,是怎么把项目搞乱的;以及怎么把它们分开。

一、先讲一下我面对的混乱

2026 年初,我接到一个工业检测项目。需求大致是这样的:

  • 现场有两个工位,每个工位有几千个 PLC 地址

  • 每个工位上有多种设备:空压机、电表、流量计,每种还有不同型号

  • 待检测的物料需要随机组合这些设备来检测

    • 物料 W1,可能进工位 1,也可能进工位 2
    • W1 检测时需要的设备组合也不固定:可能是「空压机A + 电表1 + 流量计1」,也可能是「空压机B + 电表2 + 流量计1」

也就是说,我面对的维度有:工位、设备型号、设备实例、地址段、物料、检测配置——任意两个之间都可能产生组合关系。

更糟的是,这套东西涉及前端、后端、MES、ERP 四方系统都要联动,所有人都在等架构定下来才能动。

二、第一版设计:用直觉拆模块

我当时的第一反应是按"职责"拆服务,仿照 ruoyi-vue-pro 那种多模块结构:

  • mufeng-driver:负责对接 PLC,解析地址表,把原始字节变成"设备 + 参数键值"
  • mufeng-core:负责业务,订阅 driver 的数据,落库、提供查询

driver 解析后通过 MQTT 发布:

data topic:  mufeng/data/{项目}/{设备号}
cmd  topic:  mufeng/cmd/{项目}/{设备号}

整个系统约定一份全局参数键值规范——比如 press 就是压力,单位 MPa。所有订阅方拿到的都是标准化数据,不再各自解析。

这部分我现在回头看是对的,也是后来这套架构能走通的基础。

三、然后我把自己绕进去了

问题出在我把"工位"也想塞进 driver 层

当时的直觉是这样的:物料一扫码,就要立刻知道"这个物料要用哪些设备"。但物料会出现在不同工位,同一个物料在不同工位上对应的设备组合不同——也就是同一个物料有"多个配置"。

如果不在底层处理工位,前端就要在用户扫码后问一句"你现在是在哪个工位" ,然后再决定加载哪份配置。这交互很难看,也很反直觉——人就站在工位 1 旁边,为什么还要选一次?

于是我开始在 driver 层动脑筋:能不能让 driver 知道"这个数据来自工位 1",然后帮 MES 把工位维度拆开?

但 driver 是接 PLC 的,PLC 只知道"我现在读到了第几号寄存器的值",它根本不知道什么叫工位。工位是 ERP 里的业务概念,driver 离它十万八千里。

我硬要把工位塞进 driver,就要让 driver 反过来去查 ERP——一个底层数据采集服务去查上层业务系统,这显然是错的。

但不塞,前端交互又不好。

我就这样卡了一个多月。 每天脑子里转的都是"序列号 → 物料 → 控制器 → 检测组合 → 参数 → 工位"——维度太多,没有一根能拎起来的主线。

那段时间我跟 Gemini、Cursor 各种模型聊了很久,给的答案都是"用 DDD"、"用抽象工厂"、"参考 ThingsBoard"——全是套话,没一个解决我的问题。

四、想通的那一刻

转折点其实有点反直觉:我是因为"不想改 driver"才想通的。

我对 driver 那套设计有一种很强的直觉信任感——MQTT 标准化、键值统一、设备解耦——这套东西我反复推演过很多次,越想越觉得它是对的。所以哪怕被工位问题卡住,我也下意识不愿意去动它。

某天我突然意识到一件事:

我不想改 driver,是因为 driver 没有错。 有错的是我在试图让 driver 解决一个不属于它的问题。

工位这个东西,driver 不知道、core 也不需要知道——它本来就是 ERP 和 MES 这一层的概念

只要 ERP 把"物料 → 工位 → 检测配置 → 设备组合"这条链路在业务侧建模清楚,前端扫码后直接拿到对应的配置,再去订阅 MQTT 上对应设备的数据就行。driver 一个字都不用改。

简单建模如下:

物料 → 检测配置(多对多,按工位区分)
检测配置 → 检测组合(一对多)
检测组合 → 设备列表(多对多,含参数键值映射)

那一刻我才理解了一件之前总听人说但没真正吃透的事:

业务概念不应该出现在架构层。

不是因为它不重要,恰恰相反——因为它太容易变了。今天叫"工位",换个客户叫"工序",再换个行业叫"机台"。如果架构里写死了"工位",每换一个客户都要重写底层。

设备、参数、数据流这些是不变的——任何工业场景都有设备,都有参数,都需要数据流。把架构建在不变的东西上,业务概念在上层组合,这才是真的通用。

五、验证:检测盒需求来了

架构定下来之后没多久,PM 临时塞了一个需求:要做一个"检测盒",独立的小业务,要求和 MES 完全分开。

按照旧的"业务驱动架构",这种需求基本要重做一遍。但在新架构下:

  • driver 一行不用改
  • core 一行不用改
  • 起一个新的业务模块 mufeng-detection-box,订阅自己关心的设备 topic,自己建业务模型,自己存自己的数据库

两周时间接入完毕。

那一刻我确信:这套架构不是"刚好能跑",是真的有扩展性。

六、后来想明白的事

这个项目让我意识到,架构设计最难的不是"用什么技术",是"知道哪些东西不该进架构"。

很多工业软件最后变成屎山,根源都不是代码烂,是从一开始就把业务概念硬编码进了底层。第一个客户叫工位,写工位;第二个客户叫工序,加个字段;第三个客户两个都不是,于是整个表结构推翻重来。

而真正稳的架构,是底层只认设备、参数、数据流这种业务无关的抽象,把"工位"、"工序"、"产线"这些概念全留给上层业务建模——业务变它变,业务不变它也不变。

听起来是一句很简单的话。但我是花了一个多月、亲手把自己绕进去又爬出来才真懂的。