2. 系统架构设计:整体架构图、分层设计、技术选型
好,咱们接着聊。上一章我们把需求理清楚了,这一章就该动真格的了——画架构图、定分层、选技术栈。
说实话,我见过不少团队,上来就撸代码,结果做到一半发现网络不通、协议不兼容、数据对不上。嗯,这就是典型的「架构没想清楚就动手」。我个人习惯是,先花两天把架构图画明白,后面能省一个月的时间。
2.1 整体架构图:一张图说清所有事
先上一张我常用的四层架构图。你想想看,设备远程运维,本质上就是「数据从设备流到人手里,指令从人手里流回设备」。所以分层就按这个思路来。
核心原则:每一层只干自己的事,层与层之间通过标准接口通信。别让应用层直接去读设备寄存器,那是平台层该干的活。
💡 我的经验:这张图我迭代了至少5个版本。最早只有三层,后来发现网络层单独拎出来,排查问题方便太多了。你想想看,设备连不上,到底是设备坏了、网络断了、还是平台挂了?分层清晰,定位问题就快。
2.2 分层设计:每一层都有讲究
2.2.1 设备层——最接地气的一层
设备层说白了就是那些「铁疙瘩」。PLC、RTU、传感器、边缘网关……它们负责采集现场数据,或者执行控制指令。
我在项目中遇到过最头疼的事:一台西门子S7-1200 PLC,用Modbus TCP通信,结果现场工人把网线插到了交换机上,但交换机没接外网。嗯,设备层要考虑的不仅是协议,还有物理环境。
- 通信协议:Modbus RTU/TCP、OPC UA、Profinet、CAN总线。我个人建议,新项目优先选OPC UA,安全性好,而且自带数据建模。
- 硬件选型:边缘网关建议用ARM架构的Linux板子,比如RK3588,性价比高。PLC看品牌,西门子、三菱、施耐德都行,关键是看现场工程师习惯用哪个。
- 避坑指南:我曾经遇到过设备上报数据的时间戳是设备本地时间,结果设备分布在东八区和东九区,数据全乱了。后来统一要求:所有设备上报UTC时间,平台层再转换。
2.2.2 网络层——数据的高速公路
网络层负责把设备数据安全、可靠地传到平台。这里最核心的决策是:选MQTT还是CoAP?
| 对比项 | MQTT | CoAP |
|---|---|---|
| 协议类型 | 发布/订阅 | 请求/响应 |
| 传输层 | TCP | UDP |
| 适用场景 | 频繁通信、需要推送 | 低功耗、偶尔上报 |
| 可靠性 | QoS 0/1/2 三级 | Confirmable/Non-confirmable |
| 我的推荐 | 工业场景首选 | 电池供电传感器 |
⚠️ 注意:MQTT Broker千万别用单点。我曾经在生产环境只用了一个Mosquitto实例,结果Broker挂了,3000多台设备全部离线。后来上了EMQX集群,配合Nginx负载均衡,稳如老狗。
2.2.3 平台层——系统的核心大脑
平台层是真正干活的。设备管理、数据采集、规则引擎、消息队列、时序数据库……全在这层。
我习惯把平台层拆成几个模块:
- 设备管理模块:负责设备注册、认证、影子数据。每个设备在平台上都有一个「数字孪生」,记录它的最新状态。
- 数据采集模块:从MQTT Broker消费数据,做协议解析、数据清洗。这里要注意,设备上报的数据格式可能千奇百怪,有的用JSON,有的用二进制,有的甚至用CSV。统一转换成内部标准格式再入库。
- 规则引擎:比如「温度超过80度就告警」「压力低于阈值就自动调节阀门」。我建议用轻量级的规则引擎,比如Drools或者自研的简单规则脚本,别搞太复杂。
- 时序数据库:InfluxDB还是TimescaleDB?我个人倾向TimescaleDB,因为它基于PostgreSQL,SQL查询方便,而且和业务数据可以存在同一个数据库里。
核心要点:平台层一定要做「设备影子」。什么意思?就是平台维护一份设备状态的缓存。这样应用层查询设备状态时,不用每次都去问设备,直接从缓存拿,快得多。设备离线了,影子数据还在。
2.2.4 应用层——给用户看的
应用层就是用户直接接触的部分。Web管理后台、移动端APP、大屏监控、告警推送……
这里我踩过一个坑:后台页面加载设备列表时,直接查时序数据库,结果几百万条数据,页面卡死了。后来加了Redis缓存,设备列表从缓存读,实时数据才走时序库。
- Web框架:Vue3 + Element Plus,或者React + Ant Design。我个人习惯用Vue,上手快,生态好。
- 移动端:Flutter或者UniApp。如果团队人少,建议UniApp,一套代码跑两端。
- 大屏:DataV或者自研Canvas。大屏主要是炫酷,但别为了炫酷牺牲性能。
2.3 技术选型:我的推荐清单
技术选型没有银弹,但有些组合经过验证确实好用。下面是我在多个项目中沉淀下来的推荐:
| 层级 | 组件 | 推荐技术 | 备注 |
|---|---|---|---|
| 设备层 | 边缘网关 | RK3588 + Ubuntu | 性能够用,社区活跃 |
| 网络层 | MQTT Broker | EMQX (开源版) | 支持集群,百万级连接 |
| 平台层 | 后端框架 | Spring Boot / Go Gin | Java生态稳,Go性能好 |
| 平台层 | 时序数据库 | TimescaleDB | SQL友好,支持复杂查询 |
| 平台层 | 消息队列 | Kafka | 高吞吐,数据不丢 |
| 平台层 | 缓存 | Redis | 设备影子、会话管理 |
| 应用层 | 前端框架 | Vue3 + Element Plus | 组件丰富,文档好 |
| 应用层 | 移动端 | UniApp | 一套代码,多端适配 |
💡 我的建议:别盲目追新。我见过有人用Rust写边缘网关,结果团队没人会Rust,出了问题没人能修。技术选型要考虑团队能力,稳比新重要。
2.4 避坑总结
最后,把我在架构设计阶段踩过的坑总结一下:
- 别忽略网络抖动:设备网络不稳定是常态。平台层要做好断线重连、数据缓存、消息去重。我曾经因为没做去重,设备重连后重复上报了3万条数据,把数据库打爆了。
- 协议兼容性:不同厂商的设备,同样的Modbus协议,寄存器地址可能不一样。平台层要做协议适配器,每个设备型号一个适配器。
- 安全性:设备证书认证、TLS加密、API鉴权,一个都不能少。我见过有人把设备密码硬编码在固件里,结果被黑客扫出来,整个系统被入侵。
- 可扩展性:架构设计时就要考虑未来接入10万台设备。消息队列、数据库、API网关都要支持水平扩展。
好了,架构设计这块就聊到这儿。下一章我们开始搭环境,把平台层的核心服务跑起来。