车间里挂着八块电子看板,计划员、班长、质检各看各的,最怕的就是两块屏幕上同一工序的产量数字对不上。去年我在客户现场调一个可视化电子看板项目,前后折腾了大半个月,问题恰恰就出在“多块大屏数据不同步”上。
这类项目的技术链路其实不复杂:底层是PLC、传感器或MES数据库,中间经过采集服务、后端接口,最后通过HTTP或WebSocket推送到前端大屏渲染。可一旦牵扯到多块屏,同步问题就像打地鼠一样按下葫芦浮起瓢。这篇文章我把自己在工厂可视化电子看板调试中踩过的坑、验证过的排查方法和同步机制设计思路完整梳理一遍,给正在搞大屏项目的朋友一个直接能抄的作业。
1. 数据不同步的根因,先从数据链路说起
1.1 一个大屏可视化项目的典型数据链路
工厂电子看板的数据链路,和互联网公司的BI报表有本质区别。互联网报表晚几分钟无人在意,车间看板上产量、合格率、设备状态少一个数,班组长当场就能拍桌子。
一条典型的看板链路长这样:设备层(PLC、传感器、DCS) → 采集层(串口/Modbus/OPC UA网关) → 存储层(MySQL、Redis) → 服务层(接口服务、消息推送) → 前端大屏(浏览器渲染)。数据每经过一层,就多一分偏差的可能。
我接手那个项目时,客户现场有四块车间屏、两块办公区屏、一块展示屏,一共七块。展示屏和车间屏显示的是同一套产量数据,车间屏正常刷新,办公区屏却慢了五分钟。第一反应是办公区网络差,但排查后发现网速正常。最后定位到根因:办公区大屏访问的是一个历史遗留接口,而车间屏用的是新版聚合接口,两个接口的数据源和统计口径根本不一样。
多块大屏不同步,第一步永远是画数据链路图,搞清楚每一块屏到底从哪取数。不要看IP和端口,要看到接口层和数据表层级。
1.2 六种典型“不同步”现象与根因速查
同一个“数据不同步”,现场表现五花八门。我把高频症状梳理成一张速查表,排查时先对号入座再动手:
| 现场症状 | 典型根因 | 排查方向 |
|---|---|---|
| 一块屏5秒刷新,另一块1分钟刷新 | 各屏定时器/刷新频率不统一 | 统一前端刷新策略 |
| 同一时刻两块屏产量相差几件 | 取数接口或缓存不一致 | 对比接口返回与缓存Key |
| 某块屏卡在几小时前的数据不动 | WebSocket断链未重连,或页面被节流 | 查心跳、重连和浏览器节能机制 |
| 前后两块屏时间戳差几分钟 | 系统时间未统一 | 全网NTP校时 |
| 服务重启后屏反而显示旧数据 | 缓存未失效、前端未重置 | 清理Redis并通知前端重置状态 |
| 某块屏重启浏览器后恢复,过几小时又乱 | 前端内存泄漏或消息堆积 | 检查浏览器任务管理器内存占用 |
这些现象我在不同项目里都见过,有时候一次出现两三种叠加,看起来很复杂,但只要按“源头→传输→展示”的顺序逐层排除,半小时内基本能定位。
2. 想根治,不能只靠现场“救火”
2.1 统一时钟、统一取数源,先把“时间差”干掉
很多数据不同步问题,根源是时间基准不统一。车间屏显示“当前产量 1234 件”,办公区屏显示“1233 件”,操作工说不对,但你看数据库里其实两个数都是对的——因为两块屏分别在5秒前和3秒前拉过一次数据,数据本身没有错,只是时间截点不同。
解决思路分三层:
第一层是全网校时。看板主机、后端服务器、数据库服务器全部配置NTP同步,确保“同一时刻”在各设备上是同一个时间。很多老项目服务器和看板主机时间差了十几分钟,排查问题时日志对不上,连定位都困难。
第二层是统一取数源。所有大屏只允许调用统一的聚合接口,禁止各屏自行拼装数据库查询或直连第三方接口。我在项目里定的规矩是:前端不直接访问采集表,所有指标由后端聚合服务统一输出。同一指标在七块屏上必须走同一个服务同一个方法。
第三层是引入时间戳或版本号。后端接口返回数据时带上lastUpdated字段,前端记录上一次渲染的版本号,只有新版本号大于当前版本号才更新画面。这样即使网络乱序或重复推送,旧数据也永远不会覆盖新数据。
这个设计看起来多写了几行代码,但它把“数据不同步”问题从“靠运气”变成了“靠机制”。
2.2 数据推送链路改造:轮询、WebSocket与双通道
大屏可视化项目常见两种数据推送方式:HTTP轮询和WebSocket长连接。
轮询实现简单,但问题很多。七块屏各拉各的接口,如果接口没做缓存,数据库直接被轮询请求打爆;如果做了缓存,各屏取到的缓存时间点又不一样。轮询还会产生“边缘情况”:你刚好在数据变更前一秒拉了数据,下一次拉取要等整整一个周期。
WebSocket是解决实时同步的主流方案,但只建连接不维护,照样出问题。我见过一个项目,WebSocket连上后没有任何心跳机制,路由器空闲超时把连接断了,大屏画面从此定格,只有重启浏览器才恢复。
实操中我建议做两件事:
一是必选心跳与自动重连。前端每30秒发一次ping,后端回pong,连续三次无响应则主动断开并重连。重连成功后立刻拉一次全量数据,把断线期间漏掉的数据补回来。
二是做“双通道兜底”。即使WebSocket正常,前端也要开启一个低频轮询(比如每5分钟一次),作为数据最终一致性的兜底。任何一个通道出问题,另一通道都能把画面拉回正确状态。
后端推送也要注意聚合和节流。曾经有个设备状态数据每秒变化,后端每秒都推送一次,前端渲染队列堆满,页面越来越卡。后来后端改成“2秒内多条变化合并为一条最新状态推送”,渲染压力立刻降下来。批量聚合、串行推送、必要时做消息队列削峰,是后端推送设计的三条铁律。
2.3 后端缓存与接口一致性的隐藏坑
多块大屏不同步,很多坑埋在Redis缓存里。
最常见的是缓存Key不一致。同一个产量指标,车间屏走output:line1这个Key,办公区屏走output_line1,两个Key对应两个值,数据自然对不上。查这种问题,直接用Redis可视化客户端工具连上去看Key列表,一目了然。
另一种坑是缓存过期策略不统一。同一个指标,一个接口设置了60秒过期,另一个设置了300秒,两块屏拉到的数据截点就差了好几分钟。我的习惯是:所有看板数据接口的缓存过期时间由后端统一配置,禁止各接口自行设定。
第三种坑是缓存与数据库的一致性。看板数据通常读Redis,写入时先更新数据库再失效缓存。但如果更新数据库成功、删除缓存失败,接口还会继续返回旧数据。我处理这类问题喜欢在接口里加一个“数据版本号”,每次业务数据变更版本号加一,前端把版本号显示在页面角落。现场验收时,操作工看到版本号变化,就知道数据确实更新了,这个设计后来成了我所有看板项目的标配。
3. 现场调试,别靠肉眼猜
3.1 逐段排查法:从接口Response开始逐层定位
现场调试最忌讳一上来就开抓包工具分析TCP包。正确姿势是“先看两头,再查中间”。
第一步,对比各屏的接口返回。在两块不同步的大屏上同时打开浏览器开发者工具,刷新接口,对比Response。如果两个Response的内容一致,说明问题出在前端渲染或传输环节;如果不一致,问题出在后端取数或缓存环节。
第二步,验证数据来源的时效性。直接查数据库里最新一条记录的时间戳,再对比接口返回的时间戳。如果数据库有数据而接口返回旧值,大概率是缓存问题。此时用Redis可视化客户端查看对应Key的TTL和值,基本能当场定位。
第三步,验证推送链路。WebSocket场景下,在开发者工具Network面板里过滤ws,查看最近几秒是否有消息帧进来。有消息没渲染,问题在前端;没消息但有连接,问题在后端推送或路由层。断线重连机制是否生效,也可以在这里直接观察。
这套方法我用了很多年,平均能把定位时间压缩到20分钟以内。它的核心逻辑是:不猜、不赌,把链路切成段,每一段用客观日志和响应包说话。
3.2 常用调试工具:网口调试、串口调试、抓包各有各的用法
看板项目调试工具,按用场分三类:
接口层调试,我用网口调试助手比Postman多。网口调试助手的界面更直接,可以配置多个常用请求,现场改个IP、换个参数就能立刻发请求,比在命令行敲curl直观得多。对比两块屏的接口差异时,开两个网口调试助手窗口同时请求,Response差异一眼可见。
涉及底层设备采集(比如STM32、PLC通过Modbus协议走串口或网口上报数据),串口调试助手是绕不开的工具。它能直接看到设备上发的原始报文,排查“设备数据有没有上来”“协议解析是否正常”这类问题非常高效。但我提醒一句:串口调试助手打开串口后会独占端口,如果采集服务正连着同一个串口,你这边一打开就会把服务顶掉,操作前一定要和生产确认。
底层的链路问题,比如WebSocket连接被无故断开、TCP重传严重、路由器空闲超时,这些用Wireshark抓包最靠谱。抓包文件里的TCP Keep-Alive间隔、FIN包来源,能直接告诉你连接是被谁断的、断在哪里。
工具不在多,在于用对层级。接口层用网口调试助手,设备层用串口调试助手,链路层用Wireshark,缓存层用Redis可视化工具,这一套下来覆盖了全部可疑环节。
3.3 把日志做成“现场探头”
工厂现场不像办公室,问题不会等你在电脑前慢慢复现。所以日志必须做成“探头”,问题什么时候发生,日志什么时候告诉我。
我推行了一套三级日志规范:
前端大屏日志:每次收到推送或轮询数据,console打印一条记录,包含数据版本号、时间戳、渲染耗时。页面出错时直接打印错误堆栈。现场人员按F12打开控制台,把截图发到群里,问题定位就有了第一手线索。
后端接口日志:记录每个接口的调用来源、参数、耗时、返回状态。两块屏的接口日志放在一起对比,谁调了旧Key、谁走了慢查询、谁触发了缓存重建,一清二楚。
采集服务日志:记录设备数据上来的原始值、转换后的数值、写入时间。这个环节最容易产生“隐性不同步”——设备数据本身没变,但采集服务因串口被占用或网络抖动漏采了几条,导致两块屏取到不同的数据区间。
这套日志体系搭建起来之后,我接到现场电话的频率直线下降。因为大多数问题,看日志已经能定位七七八八。
4. 高频踩坑点与避坑清单
4.1 现场高频坑位对照表
我把这几年在现场踩过的、帮别人排过的坑整理成一张对照表。每一条都是真实发生过的场景,工具和方案也都是验证过有效的:
| 坑位 | 现象 | 根因 | 处理方法 |
|---|---|---|---|
| 系统时间未统一 | 各屏时间基准差几分钟 | 未部署NTP校时 | 所有服务器和看板机统一NTP |
| WebSocket无心跳 | 大屏隔一段时间就定格 | 路由器空闲超时断开连接 | 增加心跳与自动重连 |
| 页面休眠被节流 | 次日上班屏数据空白 | 浏览器标签页后台节能 | 监听visibilitychange,恢复时拉全量 |
| 前端取数接口不统一 | 同一指标两块屏数值不同 | 各屏各自调接口 | 统一后端聚合接口 |
| 缓存Key不统一 | 同指标走两个RedisKey | 不同服务各自定义Key | 统一缓存规范并巡检 |
| 缓存过期策略差异 | 屏幕更新频率不一致 | 各接口TTL自行设定 | 后端统一配置缓存策略 |
| 服务重启未清缓存 | 重启后屏幕显示旧数 | 缓存未失效前端未重置 | 重启流程串行清缓存和重置 |
| 消息推送无聚合 | 页面越用越卡 | 高频消息堆满渲染队列 | 后端按时间窗口聚合推送 |
| 数据格式各自处理 | 合格率小数位对不上 | 前端四舍五入规则不一致 | 后端统一格式化规则 |
| 串口被多个进程占用 | 采集上报时断时续 | 调试工具和服务抢端口 | 用前确认,用完关闭 |
| 前端字段无兜底 | 页面偶发显示undefined | 某字段空值未处理 | 前端统一默认值兜底 |
| 浏览器版本过旧 | WebSocket连接异常 | 大屏主机系统老旧 | 换新内核浏览器或工控机 |
| 看板硬件残影 | 画面重影/花屏 | 显示器老化或主机带不动 | 硬件排查、重启浏览器 |
| 接口超时无重试 | 偶发整屏空白 | 后端慢查询拖垮超时 | 加超时重试和降级方案 |
这张表基本覆盖了我遇到过的90%的“多块大屏数据不同步”案例。它是排查清单,也是验收清单——项目上线前逐条过一遍,能少踩很多坑。
4.2 项目落地阶段的几条硬核经验
最后聊几条项目落地阶段才体会得到的经验,这些不是网上文档里能查到的,全是一次次熬夜换来的。
第一,改动后别只看一眼。看板数据是否同步,要观察至少十分钟。很多问题在短时间内看不出来,比如缓存过期边界、WebSocket断线周期、浏览器节流触发,都与时间相关。我习惯修改后让两块屏并排运行一两个小时,中间多次切换画面验证。
第二,大屏和业务系统的数据校验必须留“日志口”。项目上线后,现场反馈“数据不对”时,第一个动作永远是让他们打开控制台截图日志。如果日志口在交付时没留好,远程排查的成本会高好几倍。
第三,永远不要相信“应该不会有人动配置”。大屏主机的IP、浏览器缩放比例、系统自动更新、屏保和休眠设置,都可能在某个深夜被改动,然后第二天整个数据展示全乱。我在交付清单里明确写了大屏主机的标准化设置项,包括关闭系统自动更新、关闭休眠、设置浏览器开机自启动并锁定缩放比例。
第四,部署时把“数据版本号”做进页面角落。这个设计我前面提过,但值得再说一遍。版本号可见,现场人员汇报问题时能直接报出“数据版本停在多少”,你在后台看一眼当前版本就知道是前端没更新还是后端没推送,省去大量扯皮。
这个项目最终上线后,虽然陆陆续续还有一些小问题,但“多块大屏数据严重不同步”的大故障再也没有发生过。回头总结,真正起作用的不是某一招,而是把“统一时钟、统一取数源、统一推送通道、统一格式化规则、留足可观测日志”这一整套机制建起来。搞工厂可视化电子看板没有捷径,链路里的每一环都值得较真。