从PLC到Web SCADA:用网关+MQTT+Node.js搭建低成本监控系统
发布时间:2026/9/29 20:45:30来源:尧图网络
车间里的PLC每天都在忠实地跑程序控制着电机、气缸、阀门但数据却困在配电柜里。老板要产量报表你在办公室盯着触摸屏一个个记设备报警了运维人员得跑到现场看指示灯半夜停机了没人知道。等你真把数据弄出来一看无非就是Modbus寄存器里的几个数值、I/O状态或者M区、D区里的计数器本身没啥技术难度难的是怎么把这套东西安全、稳定、低成本地搬到Web上让浏览器成为新的监控窗口。这个从PLC到Web SCADA的过程我前前后后在好几个项目里趟过选型换过好几轮最后沉淀下来一套最顺手的组合工业智能网关做数据采集和协议转换MQTT做消息传输Node.js做后端服务前端再用ECharts之类的库画监控界面。整套东西下来几台设备规模的产线几千块的成本就能搞定而且不依赖任何商业组态软件的授权费。这篇就按我的实际落地过程把每一步的思路、坑和最终方案都写清楚包括环境搭建、配置参数、代码结构和排查思路希望对正在搞设备联网、数据采集的朋友有点用。1. 整条链路的设计思路从PLC到浏览器的数据通道1.1 先想清楚为什么不是PLC直连Web Server很多人第一个想法是让PLC直接通过网口或串口对接Node.js服务省掉网关这个中间环节。确实像西门子S7-1200/1500、汇川、台达这些主流PLC本身就带以太网口甚至网口Web功能理论上Node.js通过snap7或Modbus TCP库就可以直接读寄存器。但真这么干了第一批坑就会找上门。首先是PLC的CPU负载问题。PLC的循环扫描周期本来就紧张正常扫描时间如果接近看门狗设定值你再给它加上高频的外部数据请求尤其用Modbus TCP轮询的时候一个请求卡顿后面全排队。轻则通讯报文超时重则导致程序扫描周期被拉长影响设备控制精度。我实测过一台老款台达PLC用Node.js每200毫秒轮询一次M区和D区CPU负载明显上涨程序里原来的PID运算开始出现偶发抖动。其次是协议碎片化。西门子用S7协议三菱走MC协议汇川、台达支持Modbus TCP基恩士、欧姆龙又各自有一套AB的EtherNet/IP又是另一套逻辑。就算你会跟前端工程师一样写socket代码也不可能为每种PLC都从头写一套驱动。而且PLC的寄存器地址映射规则、数据字节序、字对齐方式每款都不同跨型号对接简直就是噩梦。第三是安全性和独立性。PLC直接暴露在办公网络或者云端等于把产线控制核心放到了攻击面上。即使加了密码PLC自身的权限管理也很弱一个错误报文可能直接导致设备停机。而网关单独做一层隔离PLC不直接对外通讯任何外部访问都打到网关或者后端服务上这一层隔离屏障是非常关键的。所以正解就是网关负责接入PLC把五花八门的协议变成统一的JSON或固定格式的消息通过MQTT上传Node.js只负责订阅MQTT消息存储、处理、做WebSocket推送浏览器负责展示。各司其职互不拖累。1.2 智能网关的选型逻辑边缘计算能力比价格更重要工业智能网关现在市面上牌子多得数不完从几百块的DTU到几千块的高端边缘网关都有。选型的时候别只盯着价格重点看三个指标。第一是协议转换能力。能对接你现有的PLC型号远远不够重点看它支持的从站数量和数据采集点数。有些廉价网关标称支持西门子和Modbus但实际只支持单client连接采集点数也限制在几百个产线设备稍多就不够用。第二是本地边缘计算能力。所谓边缘计算不一定要在网关里做多复杂的逻辑但至少要能在本地做数据预处理单位转换、滤波、异常判断、甚至简单的本地联动逻辑。这决定了你后面要不要为一点数据问题反复改后端代码。第三是MQTT支持参数。重点关注QoS等级支持、TLS加密、遗嘱消息。务必亲眼看到它们能在配置界面设置而不是只在说明书里写着。比如有些网关的MQTT只做简单的发布不接受订阅指令下发这意味着你没法反向控制设备那后面想做Web远程操作就不可能了。我现在的标配方案是带双网口的边缘网关一个网口接PLC网段一个接办公网/互联网网段物理隔离数据单向流转安全等级直接上一个档次。网关本地配置了Modbus TCP Master轮询周期设为500毫秒到1秒之间采集到的数据做简单的工程值转换后按JSON格式以1秒间隔发布到MQTT topictopic按工厂/产线/设备分级命名方便后端做订阅和权限管理。1.3 MQTT的角色定位不只是消息推送是整个系统的数据总线MQTT在整套架构里扮演的是中枢神经的角色它不负责存数据也不负责计算但所有数据都从它这里走。为什么选MQTT而不是直接WebSocket或者HTTP轮询关键在三个字解耦。网关采集数据Node.js消费数据二者不需要知道对方的IP和端口。网关只管往Broker上扔消息服务端只管订阅它关心的topic。这样网关可以随便换IP、换网络后端代码完全不用改动。哪怕新增一台设备也只是在网关配置里加一个采集点、发布到一个新topic后端订阅通配符topic自动收到新设备数据不需要重启服务。另外MQTT基于TCP长连接消息头发开销极低QoS机制能保证消息在异常网络下不丢。在工业现场WiFi不稳定、网线被叉车压断是家常便饭MQTT的断线重连和消息持久化机制能确保网络恢复后数据不会出现几小时的空白期。我用的Broker是Mosquitto轻量、稳定、配置简单跑在Linux服务器上内存占用可以控制在30MB以下。生产环境建议开启用户名密码认证做TLS加密同时打开持久化功能避免Broker重启导致遗嘱消息丢失。开发环境图省事可以先不搞加密但密码认证从第一天就加上不然内网其他设备扫描到1883端口就能随意收发消息。2. 核心细节拆解从PLC寄存器到MQTT消息2.1 搞清楚PLC里的数据到底是什么做这套系统的第一步不是写代码而是搞清楚PLC里到底有哪些数据。以台达PLC为例D寄存器是数据寄存器放数值、计数值、模拟量转换结果M是内部继电器相当于开关量Y是输出点X是输入点。不同品牌的PLC寄存器命名和地址不同但逻辑是一样的数据型寄存器字和位型寄存器位。我的做法是先在PLC程序里梳理出一份数据点表也就是点表。这份点表包含点位名称比如1号电机电流格式统一别一会儿中文一会儿英文缩写数据类型是16位整数、32位浮点数还是boolPLC寄存器地址比如D100、M50工程值范围比如4到20mA对应0到50Hz读写属性是只读监视还是可写控制这份点表就是整个项目的主线后面网关标签配置、MQTT的消息体设计、Web界面的展示字段全都从这张表来。我第一次做的时候懒得整理点表直接在网关配置界面里一个个找结果错位、漏点、类型搞错前前后后改了三版才稳定血的教训。2.2 网关侧的Modbus配置与数据预处理网关采集Modbus设备的数据本质就是一个标准的Modbus Master轮询过程。关键参数有四个。从站地址对应PLC的Modbus Slave地址一般是1到247之间功能码读线圈用01读离散输入用02读保持寄存器用03读输入寄存器用04。PLC数据基本都放在保持寄存器里所以一般用功能码03起始地址和数据长度对应点表里的寄存器地址轮询周期我习惯设为500ms到1s不需要太频繁除非有高速数据的需求网关采集到的原始值可能是原始的寄存器数值比如0到65535并不等于实际的工程值。以温度变送器为例4-20mA信号进入PLC的模拟量模块转换出0到32767的整数再通过工程值转换公式变成实际的0到100度。网关的标签配置里通常都有倍率和偏移量设置比如实际值等于原始值乘以0.01加上偏移量在网关里先把这层转换做掉后面后端拿到的直接就是真实物理量省了不少事。我还会在网关里做一层简单的死区过滤。所谓死区就是当前值和上一次值的差小于某个阈值时不上传比如温度波动0.1度对监控界面来说根本没有肉眼可见的区别但按1秒周期上报一天就是86400条毫无意义的MQTT消息白白增加Broker和服务端压力。把死区设为0.5度或者1%满量程照样不丢关键状态消息量能减少一个数量级。2.3 MQTT消息体设计让消息自描述网关采集数据后MQTT消息体设计直接决定了后端解析代码的复杂度。我最开始收到的网关原始消息长这样[{addr:D100,val:3267}]这种消息有俩问题。第一字段名是缩写D100是什么含义不查点表根本不知道第二没有设备标识网关如果接了两台PLC消息混在一起完全没法区分。所以后来我要求网关在配置阶段就把topic和数据格式调好最终发布的消息是这种结构{ deviceId: MIXER-01, timestamp: 1731208034, values: { motor_current: 12.5, motor_temp: 56.2, running: true, fault_code: 0 } }这样后端订阅到消息之后不需要关心来源和含义直接按照json里的key存库就行了字段的显示名和单位丢给前端配置。至于topic我按站点/产线/设备三级来命名例如。factory/line1/equipment/mixer-01 factory/line1/equipment/oven-02后端订阅factory//equipment/即可捕获所有设备消息同时保留设备维度的topic方便单机调试。3. Node.js服务端数据接收、处理与推送3.1 环境准备Node.js的安装与版本选择Node.js版本选择我建议用LTS版本目前我用的是Node.js 18.x和20.x都稳定跑过生产项目。Node.js 22的某些新特性虽然香但第三方包的兼容性不一定到位尤其是涉及原生模块的编译不过就很难受。Windows和Linux都有图形化安装包这里不详细展开只提几个关键点。npm cache路径可以改到非系统盘避免C盘爆炸环境变量确保node和npm都加入了PATH如果访问官方源速度比价慢可以配置一下国内npm镜像源但生产环境部署我更推荐用pm2守护进程来管理Node.js服务挂掉自动拉起省心。3.2 MQTT客户端接入mqtt包的基本用法Node.js生态里用mqtt包连接Broker是最常见的做法。先安装依赖。npm install mqtt基础订阅的代码框架大概是这个逻辑。const mqtt require(mqtt); const client mqtt.connect(mqtt://your-broker-ip:1883, { username: scada, password: your-password, clientId: node-backend- Math.random().toString(16).substr(2, 8), clean: false, reconnectPeriod: 3000 }); client.on(connect, () { console.log(MQTT connected); client.subscribe(factory//equipment/, { qos: 1 }); }); client.on(message, (topic, payload) { const msg JSON.parse(payload.toString()); console.log(topic, msg); // 后续处理入库、WebSocket推送、异常判断 });细节上注意几点。clientId必须全局唯一如果两个客户端用了同一个ID后面的会把前面的踢下线clean: false表示会话持久化断线重连后能收到离线期间的消息但代价是Broker要消耗资源维护会话状态如果只做实时监控对离线期间的历史消息没有要求clean: true反而轻松不用考虑消息堆积消息回调里的topic与payload都要做防御判断外网的垃圾消息、或者某个临时网关的格式异常一个JSON.parse异常就能让服务崩溃3.3 数据落库时序数据用什么存SCADA系统的数据是典型的时序数据每秒一条或多条高频写入低频查询。如果直接写入MySQL每秒成千上万条记录就有点吃力了。如果数据量不大设备点数在一百个以内每5秒一条记录MySQL也能应付但我更推荐TimescaleDB或者直接用SQLite先跑起来根据场景取舍。我的一个项目20台设备每台设备20个测点5秒间隔上报算下来每秒才80条MySQL完全没压力。但如果你要做的是一整个工厂几百台设备每秒上千条就要考虑时序数据库了。在入门阶段我建议先别上大数据组件用SQLiteWAL模式跑单机文件库或者用MySQL一张简单表就搞定等数据量真的上来了再迁移到TDengine这类秒级查询的时序库也不迟。3.4 WebSocket实时推送让浏览器不用刷新就变数据MQTT消息经过Node.js处理后要通过WebSocket推给浏览器而不是让浏览器直接连MQTT。原因很简单直接暴露1883端口给所有客户端账号密码就散出去了而且MQTT的topic权限管理对Web端并不友好。Node.js做中转后面加权限校验、数据逻辑处理、用户会话管理都很灵活。用ws库实现WebSocket服务端非常轻量。const WebSocket require(ws); const wss new WebSocket.Server({ port: 8080 }); // 存储所有已连接的客户端 const clients new Set(); wss.on(connection, (ws) { clients.add(ws); ws.on(close, () clients.delete(ws)); }); // 在MQTT message回调里调用广播函数 function broadcast(data) { const str JSON.stringify(data); clients.forEach((ws) { if (ws.readyState WebSocket.OPEN) { ws.send(str); } }); }浏览器端就是标准的new WebSocket(ws://your-server:8080)收到消息后更新界面上的数值或者状态灯。这套做法的好处是WebSocket服务只负责推送不负责业务逻辑后面真要接入AI告警还是其他系统直接在Node.js里加个模块就行改起来很快。4. Web前端可视化把数据变成一张能看的监控界面4.1 选型取舍从零写还是用现成组件库Web SCADA的前端界面我走过两条路。一条是用纯HTMLJavaScriptECharts从零拼出一套监控页面。优点是自由度高、没有框架锁定、浏览器打开就能跑非常适合数据量不大、页面逻辑简单的场景。另一条是引入Vue或React配合Ant Design这类组件库搭建复杂界面。优点是组件丰富、状态管理清晰适合页面多、交互复杂的系统但构建工具和依赖管理起来稍显折腾。如果是从0到1的入门项目我强烈建议先用纯静态页面。设备一览、实时数据卡片、历史趋势曲线、报警列表这些用ECharts加几行原生JS就够了部署的时候直接扔到Nginx里不用构建打包真的省事很多。4.2 ECharts做实时曲线从定时轮询到WebSocket接入ECharts的实时曲线核心就是setOption的series.data更新。接入WebSocket之后数据往数组里push然后图表刷新注意控制数组长度只保留最近半小时的数据点不然浏览器内存迟早被撑爆。const chart echarts.init(document.getElementById(trend-chart)); const historyData []; ws.onmessage (event) { const data JSON.parse(event.data); const point [new Date(data.timestamp * 1000), data.values.motor_temp]; historyData.push(point); if (historyData.length 360) historyData.shift(); // 保留最近一小时假设10秒一个点 chart.setOption({ series: [{ data: historyData }] }); };有个细节值得强调ECharts的时间轴不要用category类型用time类型并设置xAxis.type: time这样无论数据点的间隔是否均匀时间轴都会自动对齐否则设备断线恢复后曲线会出现锯齿感。4.3 画面布局与告警提示的人性化设计监控界面的核心不是炫技而是让现场人员一眼看到关键信息。布局上有几个原则是我做了多个项目后总结的。设备总览区放在最上方显示在线状态、设备数量、当前告警数大字、高对比度每台设备用卡片式布局卡片里放3-5个核心参数比如电流、温度、转速、状态告警区固定位置颜色要醒目红色背景白色文字声音提醒是可选的操作按钮要远离误触区域尤其是反向控制设备的按钮要二次确认告警弹出的实现不只是弹框我习惯做声音提醒加页面闪烁。有人觉得声音很烦但不做声音又会漏看我的折中方案是默认开声音界面提供一个静音按钮让操作人员自己按需选择。5. 实操过程与环节实现完整走一遍从配置到上线5.1 第一步准备硬件与软件清单硬件方面PLC一台这里以台达DVP系列为例工业智能网关一台支持Modbus TCP和MQTT普通交换机或直连网线两根一台服务器或PC装Linux或Windows都行跑Node.js和Mosquitto。软件方面MQTT Broker推荐MosquittoNode.js LTS版本VSCode或其他编辑器MQTT调试工具我用MQTT Explorer图形化界面看消息体一目了然比命令行工具适合初期排查问题。5.2 第二步PLC端准备与Modbus映射先在PLC编程软件里新建一个工程写一段简单的测试逻辑。这里以台达的WPLSoft或者ISPSoft为例往D100到D104写一组有规律的数值比如让D100自加一模拟一个计数器。然后在D200存一个温度值用手动赋值模拟。PLC的通讯参数设置是常见的卡壳点。注意台达PLC的Modbus TCP从站地址和端口号默认是502必须确保PLC的网口IP和网关能通。我踩过的坑是PLC的IP和上位机不在一个网段导致网关根本连不上PLC而且这类问题最迷惑因为看起来软件、参数都对就是不通。实际用生产环境前可以先直接用Modbus Poll工具验证PLC的寄存器能读到数据再往下配网关。5.3 第三步网关配置与MQTT发布网关的配置虽然品牌不同但逻辑相似。先设置网关本身的位置例如网口1接PLC设为192.168.0.10网口2接服务器设为192.168.1.10。然后在网关里新增一个从站连接设置PLC的IP、端口、从站地址。再创建一个采集分组把D100和D200映射为标签设置数据类型为16位无符号整数采集周期1秒。最后在网关的MQTT配置页面填入Broker的IP和端口、用户名密码、发布topic。配置完成后用MQTT Explorer连上Broker订阅通配符#大约1秒后应该能看到网关发布上来的JSON数据。这一步如果没数据优先排查网关到Broker的连通性其次是确认topic写对了没有。这里顺便提一句inproshow或者Codesys这些软件里设置的PLC端口号问题。每款PLC的默认端口都不一样比如西门子S7协议用102端口Modbus TCP用502。如果网关里配置好了但采集不到数据先检查是不是端口号写错了这个错误极其常见而且报错提示往往不明确。5.4 第四步Node.js后端服务搭建5.4.1 安装并启动MosquittoLinux服务器上安装Mosquitto很简单。# Ubuntu/Debian sudo apt install mosquitto mosquitto-clients # 编辑配置 sudo vim /etc/mosquitto/mosquitto.conf配置里核心几项。persistence true persistence_location /var/lib/mosquitto/ allow_anonymous false password_file /etc/mosquitto/passwd listener 1883Mosquitto设置密码sudo mosquitto_passwd -c /etc/mosquitto/passwd scada # 然后输入两次密码 sudo systemctl restart mosquitto如果不想用系统服务手动把zip包解压出来跑Windows上可以用mosquitto -c mosquitto.conf指定配置文件启动效果一样只是没有开机自启而已。5.4.2 用Node.js跑通全流程新建一个项目目录初始化。mkdir scada-backend cd scada-backend npm init -y npm install mqtt ws sqlite3然后写一个server.js把MQTT订阅、数据入库、WebSocket推送串起来。关键代码如下为了节省篇幅只保留核心逻辑。const mqtt require(mqtt); const WebSocket require(ws); const sqlite3 require(sqlite3).verbose(); const db new sqlite3.Database(./scada.db); db.run(CREATE TABLE IF NOT EXISTS telemetry (id INTEGER PRIMARY KEY AUTOINCREMENT, device TEXT, ts INTEGER, key TEXT, value REAL)); const mqttClient mqtt.connect(mqtt://localhost:1883, { username: scada, password: your-password, clientId: node-backend-mm01, clean: false }); const wss new WebSocket.Server({ port: 8080 }); const wsClients new Set(); wss.on(connection, ws { wsClients.add(ws); ws.on(close, () wsClients.delete(ws)); }); function broadcast(payload) { const msg JSON.stringify(payload); wsClients.forEach(ws { if (ws.readyState WebSocket.OPEN) ws.send(msg); }); } mqttClient.on(connect, () { console.log(MQTT connected); mqttClient.subscribe(factory//equipment/, { qos: 1 }); }); mqttClient.on(message, (topic, payload) { const data JSON.parse(payload.toString()); const ts data.timestamp || Math.floor(Date.now() / 1000); Object.entries(data.values || {}).forEach(([key, value]) { db.run(INSERT INTO telemetry (device, ts, key, value) VALUES (?, ?, ?, ?), [data.deviceId, ts, key, typeof value number ? value : (value ? 1 : 0)]); }); broadcast({ topic, data }); }); console.log(SCADA backend started);这样一整条链路就通了网关采集PLC数值发布到MqttNode.js订阅并注入SQLite同时通过WebSocket推送给前端浏览器里数据实时刷新。整个流程不到100行核心代码比买商业组态省出一大截。5.5 第五步前端页面可视化前端就一个index.html引用ECharts CDN连上WebSocket做个最简单的卡片显示。!DOCTYPE html html head meta charsetutf-8 title车间监控看板/title script srchttps://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js/script /head body div idapp styledisplay:flex;gap:16px;flex-wrap:wrap;padding:16px div classcard idcard-temp h31号电机温度/h3 p classvalue idmotor-temp--/p /div /div script const ws new WebSocket(ws://your-server:8080); ws.onmessage (event) { const msg JSON.parse(event.data); const data msg.data || {}; const values data.values || {}; if (values.motor_temp) { document.getElementById(motor-temp).textContent values.motor_temp °C; } }; /script /body /html只要能跑通这版后面的页面加设备卡片、加趋势图、加告警列表只是重复扩展没有新门槛了。6. 常见问题与排查技巧实录6.1 网关连着PLC却采集不到数据最优先排查基础网络连通性。在网关的调试界面或者PC上用ping命令测试PLC的IP大部分情况是设备的IP和网关不在同一个网段或者PLC的防火墙拦截了Modbus端口。还有台达PLC默认的Modbus通讯功能未启用需要在PLC程序里把通讯功能打开这一步容易被忽略。第二排查寄存器地址。许多PLC的Modbus寄存器地址是0-based的而你在点表里看到的地址是1-based的比如点表写的D100其实Modbus地址是999或者1000的偏移。每一个PLC品牌在这个细节上都不太一样需要参考协议手册确认。上Modbus Poll工具手动读一遍就知道该填多少了。6.2 MQTT消息时有时无或者掉线重连后会丢数据这个问题分两种。如果是网络原因导致的断线需要检查一下WiFi信号强度或者网线质量工业现场干扰源多昨天还在用什么今天就动不动掉线优先怀疑物理链路。如果是Broker重启后消息丢失大概率是没开持久化或者客户端用了clean: true。配置改成persistence true客户端设clean: false再配合QoS 1或者2绝大多数丢消息问题能解决。另外如果你发现每秒一次的数据在断线重连瞬间会涌入一大波那是正常的排队消息是MQTT的会话机制在把离线期间没发出去的消息补发。此时前端要能接受稍微密集的推送后端入库最好做批量插入而不是逐条避免瞬间把CPU跑爆。6.3 Node.js服务内存占用越来越高Node.js服务跑时间长了内存涨上去绝大多数是数组或Map只增不减。比如前面前端趋势图提到要shift()旧数据后端也一样。如果有缓存历史消息到内存里的逻辑务必设一个上限。另一个常见问题是WebSocket连接没有清理客户端断线后close事件没触发或者触发失败连接对象一直留在Set里导致内存泄漏。因此建议定期检查连接心跳超过30秒没心跳的直接主动terminate掉。6.4 数据乱码、负数或者单位不对Modbus读取到的原始字节存在字节序问题。西门子PLC通常是big-endian台达是little-endian。网关配置里一般能选如果选错了读出来的值可能是个很大的数字或者负数、小数位错乱。同理32位浮点数如果按16位整数解析读出来的值肯定会离谱。单位不对一般就是倍率和偏置算错了。比如4到20mA对应0到50Hz如果你直接把原始Lsb值当成Hz那肯定不对要在网关配置里正确做初等数学转换。6.5 常用排查工具组合我平时排查链路故障的位置会带三样工具。Modbus Poll或Modbus Slave用来验证PLC寄存器值确实能读取MQTT Explorer用来验证网关是否在发布消息、消息格式是否符合预期浏览器开发者模式Network和Console标签看WebSocket连接状态和报错这三样工具加一个通用的IP连通性检查能覆盖90%链路故障的排查场景。7. 进阶方向从能用到好用还需要做哪些事到这里从PLC到Web SCADA的基本链路已经完全跑通了。剩下的是这个系统从“能用”变得“好用”的工作顺着我的经验给你几个方向。第一设备反向控制。现在只是把PLC的数据读了出来如果需要通过Web页面远程修改PLC的参数操作寄存器或者M区就要在网关或者Node.js里加一个指令下行的通道。MQTT本身就是双向的网关能接收订阅然后通过Modbus写寄存器这就是远程控制。但可靠性、权限、安全尤其是防止误操作比实时监视要复杂得多。第二历史数据分析和报表。SQLite存下来的数据可以做一个日报表统计比如当天产量、运行时长、故障次数、能耗累计。SQLite的数据量大了可以迁移到TimescaleDB然后加上Grafana数据可视化直接少写一半代码。第三报警管理。现在只是在页面上弹个框生产环境需要的是报警去重、报警升级、短信通知、报警记录追溯。MQTT本身的遗嘱和retain消息可以对设备离线告警做检测但完整的告警生命周期管理需要后端设计一整套状态机。第四权限管理。如果系统要给多个角色用操作员只能看工段长能看能操作管理员要管配置那就得引入用户体系了JWT、Session二选一再加一个操作日志留痕。我个人体会是这类项目最大的瓶颈从来不在技术而在数据源头的梳理——点表有没有理清楚、网关配置有没有踩到字节序的坑、现场网络稳不稳定。只要把源头的数据捋顺了后面的技术环节反而都是顺水推舟的事。把这些基本功做扎实哪怕设备再多、现场再复杂终究只是复制粘贴式的横向扩展不会有本质性的新难题。
网站建设高端定制企业官网