简介:KEPServer作为工业数据采集与交换平台,常被用于连接西门子PLC与MySQL数据库。这份doc文档面向需要配置KEPServer主备切换、实现MySQL与西门子S7-1500双向读写、以及管理后台服务的自动化工程师,内容涵盖32位ODBC驱动配置、通道/设备/标记的建立、连接MySQL与PLC的具体步骤、Data logger数据映射及MySQL反控PLC的Link Tag方法,并补充了地址值录入规范、主备切换提高可靠性和后台服务启停要点。包体为单份doc文档,大小1.9MB,结构按使用配置、功能解析、连接MySQL、连接PLC、数据映射等模块展开,方便按需查阅。目前已有728人学习下载,适合正在搭建KEPServer与西门子PLC、MySQL互通方案的工业现场技术人员。
1. KepServer 三件套:主备、双向读写、后台服务,为什么总在现场翻车
同样一份项目文件,在办公室测试环境怎么跑都正常,上了产线就出幺蛾子:主备一切换,OPC 客户端掉线,MySQL 里温度值突然翻倍,后台服务重启后工单写进 PLC 变成 0。这不是玄学,而是把 KepServer(Kepware)当普通软件装了。标题里的主备、MySQL 与西门子双向读写、后台服务、地址填写,其实是同一个问题的四个面:数据链路怎么设计、进程怎么保活、地址怎么填对。这篇笔记按现场落地的顺序拆开讲,适合正在做产线数据采集、MES 对接或双机冗余改造的工程师照着复现,也把不太容易在界面上踩到的坑提前标出来。
2. KepServer 主备冗余:先搞清同步机制,再动心跳参数
2.1 主备架构怎么选:热备、冷备与冗余的本质区别
很多人第一次上主备,是把两台机器同时启动、同时对外服务,以为能像负载均衡一样分担压力。KepServer 的冗余不是这个逻辑。它是一主一备,主节点正常工作时,备节点只做两件事:通过专用心跳通道监视主节点状态,定期同步项目配置和运行时标签值。一旦主节点失联超过设定次数,备节点才在切换延时结束后接管服务,对外提供 OPC UA / OPC DA 访问。
选型上先回答一个问题:你的现场能不能接受几分钟的数据断流?如果只是做监控大屏,断三分钟无所谓的,单机加 UPS 都比上双机划算。真正需要主备的是数据不允许丢的环节,比如工单下发、连续工艺参数记录,或者 SCADA 系统没有断线重连能力。另一种常见误区是以为备机能顺便当开发测试机,实际上备机在热备状态下持续同步运行数据,拿它跑别的项目会污染标签缓存,切记分开。
KepServer 的冗余建立在相同版本、相同项目文件的基础上。两台机器装同一个版本,把主机做好的项目复制到备机,启用了冗余之后,运行时的标签值才由主节点往备节点同步。配置文件的同步靠手动复制,不是自动的,代码过程序改了通道、加了标签,要记得同步到备机,否则切换后备机还是老配置。
2.2 最小可用配置:开启冗余、绑定专用网卡、设置切换延时
配置路径在管理工具的 Project Properties 里,找到 Redundancy 选项卡。启用前先把准备工作做掉:两台机器各配一块独立网卡专门跑心跳,不要和生产网络、OPC 客户端网络混在一起。生产网络一拥堵,心跳包跟着丢,系统会误判主节点故障,来回切换比主节点真故障还可怕。
配置顺序按下面走,这是常见做法,每一步都有参数需要解释。
操作步骤(GUI 界面):
- 在主机上完成通道、设备、标签的全部配置,保存项目文件,复制到备机。
- 打开主机 Project Properties → Redundancy,勾选 Enable Redundancy。
- 填写本机冗余 IP 和伙伴冗余 IP,即两台机器上心跳网卡的 IP。
- 设置心跳间隔、失联判定次数、切换延时。
- 可选配置 Virtual IP,这个 IP 在切换时由备机接管。
- 先启动备机,再启动主机,确认状态分别显示 Primary、Secondary。
参数推荐值见下表,实际要根据网络质量微调。
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 心跳间隔 | 1000 ms | 备机发送心跳报文的周期,太短增加 CPU 开销,太长切换慢 |
| 失联判定次数 | 3 次 | 连续丢 3 个心跳包才判定主节点故障,过滤偶发丢包 |
| 切换延时 | 5000 ms | 判定故障后等待的时间,给网络抖动留缓冲 |
| 虚拟 IP 切换 | 启用 | OPC 客户端连接虚拟 IP,切换后无感知 |
| 心跳网卡带宽 | 独立 100 Mbps 即可 | 心跳包很小,但必须独立,避免受广播风暴影响 |
这里重点说切换延时。设成 0 看起来切换最快,但生产网里一个广播风暴就能让心跳连续丢包,系统会在几秒内来回切换,备机刚接管主机又恢复,客户端反复断连。我一般给 3 到 5 秒,宁可切换慢一点,也不要误切换。失联判定次数和切换延时配合,整体故障响应时间大约是:心跳间隔 × 判定次数 + 切换延时。按上表就是 1 秒 × 3 + 5 秒,约 8 秒完成接管,对这个量级要有预期。
虚拟 IP 是另一个取舍。启用之后客户端必须改连虚拟 IP,切换时由备机通过网卡绑定接管,客户端完全无感;如果不用虚拟 IP,客户端就得自己做断线重连,重新解析到备机的 IP。没有虚拟 IP 的冗余方案,严格说只能算半自动恢复,因为客户端的重连逻辑通常不可控。
提示:冗余状态下两台机器的标签值同步不是实时的,存在一个同步窗口。主节点写入标签后立即故障,尚未同步到备机的最后几个值会丢。数据库落库如果依赖标签值,要在应用层做补偿,后面第 3 章会提到。
2.3 主备切换的隐性代价:标签同步延迟与虚拟 IP 的取舍
主备切换时,PLC 侧也会受影响。KepServer 和西门子 PLC 之间的 S7 连接在主节点故障后是断开的,备机接管后需要重新建立 TCP 连接,PLC 那边如果没做多主站支持,甚至会短暂报连接错误。所以主备切换测试不能只看 OPC 客户端是否重连成功,还要去 PLC 的诊断缓冲区里看通讯错误记录。
备机的标签值同步机制也要摸清楚。它同步的是运行时的值缓存,而不是历史数据。这意味着切换到备机后,备机上不会自动补出主机故障期间那几分钟的数据。如果下游 MySQL 需要完整的数据序列,应该在写入逻辑里做断点续传,或者在 PLC 程序里加数据缓存区,而不是指望 KepServer 冗余来兜底。
我见过一个项目,主备切换都测通过了,结果某次主机硬件故障,切换后 MES 系统发现 MySQL 里缺了 4 分钟数据,最后还是给 PLC 加了个 FIFO 缓冲区,把掉线期间的数据缓存到恢复后补传,这才彻底解决。KepServer 冗余保证的是服务连续,不是数据完整,这是两回事,预算和方案设计时一定要分开评估。
3. MySQL 与西门子双向读写:两条数据通路,两种触发机制
3.1 双向读写链路设计:谁轮询、谁触发、谁保证一致性
MySQL 和西门子 PLC 通过 KepServer 做双向读写,实际是两条方向相反、机制完全不同的通路。PLC 到 MySQL,用 KepServer 自带的 DataLogger 插件按周期或变化触发写入,这是采集链路。MySQL 到 PLC,KepServer 本身没有特别顺手的原生功能,常见的做法是外置一个桥接服务,它去 MySQL 里取待下发数据,再通过 OPC UA 把值写进 KepServer 标签,由 KepServer 转写进 PLC,这是下发链路。
两条链路的触发机制要分开设计。采集链路是 KepServer 主动轮询 PLC 标签,变化触发适合离散量、周期触发适合连续量。下发链路是桥接服务轮询 MySQL 数据表,拿到新工单后写 PLC,PLC 侧要有握手位来确认已经执行。如果两条链路都做成高频轮询,会出现同一个标签被两个进程同时操作的竞争条件,数据相互覆盖。
在动手之前,先用表格把方案对比看清楚,避免做了一半发现路径错了。
| 方案 | 采集方向(PLC→MySQL) | 下发方向(MySQL→PLC) | 适用场景 |
|---|---|---|---|
| PLC 直连 MySQL | 需要 PLC 支持 SQL 通讯,S7-1200 可以但工程量大 | 同上 | 新项目、PLC 程序可控 |
| KepServer + DataLogger | 原生支持,配置快 | 不支持 | 已有 KepServer,MES 只读数据 |
| KepServer + 外部桥接 | DataLogger 负责 | Python/C# 脚本负责 | 双向对接最常见做法 |
| 中间库 + 文件交换 | 通过 CSV/JSON 文件中转 | 同上 | 两侧网络隔离,低实时性 |
大多数存量产线选第三行。PLC 程序不用动通讯逻辑,MySQL 也不用给 PLC 开账号,安全边界清晰。
3.2 PLC→MySQL:DataLogger 插件的建表与最小配置
先做数据表。MySQL 里建一张通用采集表,字段设计直接影响后续查询效率,别把所有标签塞进一张动态列的表里,调试的时候会很想哭。
建表 SQL 如下:
CREATE TABLE `plc_data` ( `id` BIGINT AUTO_INCREMENT PRIMARY KEY, `tag_name` VARCHAR(64) NOT NULL, `tag_value` DOUBLE, `quality` TINYINT, `write_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY `idx_tag_time` (`tag_name`, `write_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;逻辑说明:tag_name 存 KepServer 的标签路径,比如Channel1.Device1.Temperature;tag_value 用 DOUBLE,覆盖 INT、REAL 和大部分模拟量;quality 存 OPC 质量码,192 表示 Good,0 表示 Bad,写入后可以筛脏数据;write_time 由数据库生成,不要从 PLC 或 KepServer 侧带时间戳,因为 PLC 的时钟通常没有做 NTP 同步,时间会漂。索引建立在 tag_name 和 write_time 上,查询某标签某时段数据走索引很快。
接下来在 KepServer 管理工具里配置 DataLogger。前置条件是安装 MySQL ODBC 驱动,并在 ODBC 数据源里新建一个系统 DSN,名字比如叫 KepMySQL。
配置步骤:
- 管理工具 → DataLogger → 新建 Data Store,类型选 ODBC。
- 写入连接串,选择系统 DSN KepMySQL,填 MySQL 账号密码。
- 指定目标表 plc_data,把 tag_name、tag_value、quality 分别映射到表的对应字段。
- 添加要记录的标签组,选择触发方式。
- 打开 DataLogger 的记录开关,确认日志里没有 SQL 报错。
触发方式按数据类型来选。温度、压力这类连续模拟量用周期触发,1000 ms 记录一次,数据平稳时会产生大量重复值,但曲线完整。设备状态、故障位这类离散量用变化触发,只有值变化时才写入,数据量小,而且能看出动作发生的精确时刻。生产数据归档我一般不做纯周期,固定 1 秒写一次全标签,数据量级可以接受,但标签多的时候 MySQL 写入压力明显,要提前做压测。
这里有个容易踩的细节:DataLogger 的写库失败重试机制。MySQL 瞬间重启或网络闪断时,DataLogger 会缓存未写入的数据,但缓存有上限,超出上限就开始丢。建议把缓存设到能覆盖 10 分钟以上的故障窗口,同时加一个定期检查 MySQL 连通性的监控,发现断连就告警。
3.3 MySQL→PLC:用 OPC UA 桥接脚本下发工单,含可抄作业代码
下发方向我用 Python 脚本做桥接,逻辑不复杂:轮询 MySQL 中状态为待下发的工单,通过 OPC UA 写入 KepServer 标签,等 PLC 返回握手位,再把工单状态置为已下发。核心是幂等处理,不能因为脚本重启就把同一条工单重复下发两次。
下面是一个可改可用的脚本骨架:
import time import mysql.connector from opcua import Client # 标签路径和 OPC UA 端点以 KepServer 实际配置为准 OPC_UA_URL = "opc.tcp://192.168.1.10:49320/KEPServerEX/UA" PLC_TAGS = { "order_id": "ns=2;s=Channel1.Device1.MW10", "order_qty": "ns=2;s=Channel1.Device1.MW20", "order_ack": "ns=2;s=Channel1.Device1.M30.0", } DB_CONFIG = { "host": "192.168.1.50", "user": "bridge_user", "password": "your_password", "database": "mes", "charset": "utf8mb4", } def fetch_pending_orders(): """从 MySQL 取待下发工单,SELECT 和 UPDATE 必须在同一事务里做,防止重复取数""" conn = mysql.connector.connect(**DB_CONFIG) cur = conn.cursor(dictionary=True) cur.execute("SELECT order_id, qty FROM mes_order WHERE status=0 LIMIT 5 FOR UPDATE") rows = cur.fetchall() for r in rows: cur.execute("UPDATE mes_order SET status=1 WHERE order_id=%s", (r["order_id"],)) conn.commit() cur.close() conn.close() return rows def write_to_plc(rows): client = Client(OPC_UA_URL) client.connect() try: for r in rows: client.get_node(PLC_TAGS["order_id"]).set_value(r["order_id"]) client.get_node(PLC_TAGS["order_qty"]).set_value(r["qty"]) # 等待 PLC 握手位翻转,确认 PLC 已读取本次工单 deadline = time.time() + 5 ack_node = client.get_node(PLC_TAGS["order_ack"]) while time.time() < deadline: time.sleep(0.2) if ack_node.get_value() is True: break else: print(f"order {r['order_id']} timeout, please check PLC logic") finally: client.disconnect() if __name__ == "__main__": while True: pending = fetch_pending_orders() if pending: write_to_plc(pending) time.sleep(0.5)逻辑说明:fetch_pending_orders 用 FOR UPDATE 把待下发工单锁住,并在同一个事务里把 status 置为 1,这样即使脚本在处理过程中崩溃,重启后也不会重复取到同一条工单。write_to_plc 通过 OPC UA 写 MW10 和 MW20,然后轮询 PLC 的握手位 M30.0,PLC 程序里收到工单后把这个位置 1,脚本确认后才继续下一条。这个握手机制是双向读写里必须有的,否则 PLC 还没处理完,下一条工单就覆盖过来了。
参数说明:轮询间隔 0.5 秒对下发类业务足够,不需要更短,太短会给 KepServer 和 PLC 增加无意义通讯负载;OPC UA 端点里的端口默认是 KepServer 的 UA 端口,不同版本可能不同,在管理工具的服务端点设置里查;节点 ID 的 ns=2;s= 格式可以在 KepServer 的 UA 配置里看到,或者用 UA Expert 扫一下。
提示:脚本跑起来后要打包成 Windows 服务,和 KepServer 一样做开机自启、崩溃重启,否则桥接进程一挂,下发链路就断了,而且没有任何提示。下一章讲服务化。
4. 把 KepServer 跑成后台服务:账号权限、自动重启与监控习惯
4.1 为什么必须服务化:注销、断连、自启三个绕不开的场景
开发阶段我见过不少同事直接以管理员身份打开 KepServer 界面跑数据,功能调试完全没问题,问题出在部署后。远程桌面一断开,Windows 会注销当前会话,以交互方式运行的 KepServer 进程随之退出,PLC 数据断流。更要命的是,现场突然断电恢复后,服务器自动重启,但没有人去登录桌面双击启动,KepServer 就一直停在那里,直到产线报数据异常才发现。
KepServer 安装时可以选择以 Windows 服务方式运行,也可以在安装后通过管理工具切换。服务模式下,进程由 Windows 服务控制管理器(SCM)托管,不依赖任何用户登录会话,服务器重启后会自动拉起,账号注销也不影响。这是产线部署的底线要求,不是可选项。
切到服务模式后,管理工具仍然可以连接配置,它会作为客户端连到后台服务。需要注意的一点是,不要在服务运行时用管理工具反复开关项目,每次操作都会触发通道重连,现场 PLC 那边会看到连接抖动。
4.2 服务账号与权限:LocalSystem 能跑,为什么写不了 MySQL
KepServer 服务默认可以用 LocalSystem 账号跑,本地通讯、启动进程都没问题。但 LocalSystem 在跨网络访问时身份是本机的计算机账号,MySQL 服务器上如果不允许这个主机访问,或者需要访问网络共享、域资源,就会直接失败。现象往往是:服务能启动、OPC 通讯正常,但 DataLogger 写 MySQL 报 Access denied。
常见做法是创建一个专用 Windows 账号,比如.\kep-svc,密码设成永不过期,只给必要的权限。然后用下面的脚本修改服务登录账号和恢复选项。
# 查看 KepServer 实际的服务名,避免记错 sc.exe query | findstr /i kep # 修改服务登录账号(服务名以实际查到的为准) sc.exe config "KEPServerEX" obj=".\kep-svc" password="你的密码" # 配置服务故障恢复:失败后 60 秒重启,连续三次都重启,24 小时后重置计数器 sc.exe failure "KEPServerEX" reset= 86400 actions= restart/60000/restart/60000/restart/60000逻辑说明:第一条命令先查服务名,不同版本的服务名不一样,直接照着文档写容易报错。obj 参数指定账号,.\kep-svc 表示本机账号,如果用域账号就写 域名\账号。failure 是服务恢复配置,reset= 86400 表示 24 小时后重置失败计数器,避免长时间运行后一次小崩溃就触发修复逻辑;actions 里三个 restart/60000 分别表示第一次失败、第二次失败、第三次失败都以重启响应,间隔 60 秒。
MySQL 侧还要给 bridge_user 和 DataLogger 用的账号单独授权,原则是最小权限。只给 INSERT、SELECT、UPDATE 权限就够了,不要用 root。如果 MySQL 和 KepServer 在不同机器,MySQL 用户授权时要明确允许来自 KepServer 所在主机的连接。
注意:改完服务账号后,必须重启服务才能生效。另外,如果服务之前以 LocalSystem 跑过并缓存了某些网络连接,切换账号后可能继承不了,重启一次系统更干净。
4.3 服务异常重启:恢复选项、日志定位与黑匣子排查
服务配了自动重启,不代表问题就自动消失了。重启只能恢复服务进程,不能恢复损坏的项目配置或失效的驱动授权,更不会补偿重启期间丢失的数据。所以要把日志留好,排查的时候才不会面对黑匣子。
KepServer 自身有事件日志,记录通道状态、设备连接、标签读写和冗余切换事件。在管理工具的日志视图里可以看到,也可以把日志输出到文件。Windows 事件查看器里同样会有服务启动、停止、崩溃的记录。崩溃时要对比两边日志:KepServer 日志能看到它最后在做什么操作,Windows 日志能看到崩溃的模块路径、异常代码。
另一个常见问题是服务自动重启后,管理工具界面显示服务在运行但连接不上,或者所有标签都是 Bad Quality。这通常是服务启动时没有成功加载驱动或项目文件损坏。排查顺序是:先看 Windows 事件日志里服务是否报了异常,再看 KepServer 日志里项目加载是否完成,最后看许可证是否有效。项目文件损坏的,直接拿备机或主机上的备份覆盖,不要试图在损坏的项目上修复。
5. 地址填写与常见问题排查:从连接失败到数据错位
5.1 西门子 S7 地址填写:I/Q/M/DB 的位、字节、字、双字对照
KepServer 的西门子驱动地址看起来简单,填错的表现却很隐蔽:不是连不上,而是连上之后数值错乱。地址格式必须和 PLC 里的数据类型严格对应。下面是最常用到的地址对照表。
| PLC 区域 | 位 | 字节 | 字(16 位) | 双字(32 位) | 说明 |
|---|---|---|---|---|---|
| 输入 I | I0.0 | IB0 | IW0 | ID0 | 不可写,只读 |
| 输出 Q | Q0.0 | QB0 | QW0 | QD0 | 可写 |
| 位存储 M | M0.0 | MB0 | MW0 | MD0 | 最常用,变量区 |
| 数据块 DB | DB1.DBX0.0 | DB1.DBB0 | DB1.DBW0 | DB1.DBD0 | DB 号别填错 |
地址填写的真正难点不是格式,而是数据块偏移。PLC 程序在 TIA Portal 里定义 DB1 的偏移如果是 0.0、2.0、4.0,KepServer 里填 DB1.DBW0、DB1.DBW2、DB1.DBW4,这个一致性好对齐。但很多 PLC 程序经过多次修改后,变量排列中间有空隙,绝对地址和程序里的符号名对应不上。经验是先让 PLC 程序导出一份交叉引用表,确认每个变量的实际偏移再填。
S7-1200 和 S7-1500 还有一个专属坑:数据块默认启用了优化的块访问。启用后,绝对地址不存在,KepServer 的绝对地址访问会失败。解决方法是两种,要么在 TIA Portal 的数据块属性里取消勾选优化块访问,要么用支持符号寻址的驱动配置方式。改造老项目往往动 PLC 程序比较敏感,尽量选后者。
字节顺序也要统一。西门子 PLC 是大端,KepServer 的驱动驱动里如果默认按小端解析,读回来的 INT 没问题,但 DINT 和 REAL 会对调高低字节,数值会变得很大或很小。遇到这种数值看起来完全不对的,先查 Byte Order 参数,再查数据类型,不要先怀疑网络。
5.2 MySQL 连接串与系统 DSN:后台服务必须踩对的两个细节
DataLogger 和外部桥接脚本连 MySQL,连接层面最容易翻车的地方有两个:一个是 DSN 配成用户级还是系统级,另一个是字符集。
KepServer 是后台服务,服务在用户未登录时启动,它读不到用户级 DSN,只能读系统级 DSN。所以配置 ODBC 数据源时一定要选系统 DSN,而不是用户 DSN。DSN 名字不要用中文,不要带空格,比如KepMySQL,否则连接串里转义麻烦。
连接串写法如下,适用于 MySQL ODBC 8.0 驱动:
DRIVER={MySQL ODBC 8.0 Unicode Driver};SERVER=192.168.1.50;PORT=3306;DATABASE=mes;UID=kepuser;PWD=your_password;charset=utf8mb4;OPTION=3;参数说明:DRIVER 要和实际安装的 ODBC 驱动名称一致,不要照抄;charset 设成 utf8mb4,否则中文工单号、备注信息写进 MySQL 会乱码或报 Illegal mix of collations;OPTION=3 是一个常见组合值,表示启用自动重连和快速查询,具体含义以 ODBC 驱动文档为准。DataLogger 里填连接串,如果测试连接时报证书或加密相关错误,在连接串里加上SSLMode=DISABLED,但仅限内网环境,公网绝对不要关加密。
桥接脚本连 MySQL 时,Python 侧要用参数化查询,不要用字符串拼接 SQL。这既是防注入的要求,也是防止中文字段在 SQL 拼接时编码错乱的最简单办法。
5.3 避坑清单:五个真实翻车现场与解决路径
第一条,地址格式报错。现象:KepServer 设备状态变成 fault,日志提示地址无法解析。原因:不同版本驱动对 DB 地址的分隔符要求不同,有的认点号DB1.DBX0.0,有的认逗号DB1,DBX0.0。解决:先看驱动文档的地址示例,用管理工具自带的地址校验功能试几种分隔符,不要一次批量填几百个标签再统一报错。
第二条,写入 MySQL 的温度值翻倍。现象:PLC 里是 25.5 度,数据库里是 51.0 或 63.0,而且只出现在 REAL 类型模拟量上。原因:字节序配错,或者 KepServer 标签类型定义成了 DINT 而 PLC 实际是 REAL。解决:改驱动通道的 Byte Order 为与 PLC 一致,再核对标签数据类型,调试时用同一时刻的 PLC 监视值和数据库值做对比,确认一致后再批量改。
第三条,S7-1500 的 DB 块连接失败。现象:S7-1200/1500 设备的 DB 地址全部通讯失败,M 区正常。原因:DB 开启了优化块访问,绝对地址无法直接读取。解决:在 TIA Portal 的数据块属性中取消优化块访问后重新下载,同时注意,取消优化后 PLC 程序的符号访问可能受影响,必须先和 PLC 程序负责人确认变更窗口。
第四条,服务重启后 DataLogger 不再写库。现象:KepServer 服务正常,OPC 通讯正常,但 MySQL 里没有新数据。原因:服务账号之前用 LocalSystem,重启后切成了专用账号,MySQL 侧没有授权该账号来源主机,或者系统 DSN 在账号切换后读不到。解决:检查 MySQL 用户表里的 host 字段,确认包含 KepServer 这台机器,再确认 DSN 是系统级,测试连接时用服务账号手动跑一次查询验证。
第五条,双向读写时工单号偶发变成 0。现象:外部脚本写入 MW10 后,PLC 读到的偶尔是 0,数据库状态却被置为已下发。原因:脚本写 OPC UA 标签时,KepServer 正在按周期采样该标签,采样动作和写入动作竞争,或者 PLC 侧读取时序和写入时序冲突。解决:加握手位,脚本必须等 PLC 确认信号再更新数据库状态,同时把采集链路里对 MW10 的周期触发改为变化触发,避免两边同时操作。
6. 上线前做个三连演练:切换耗时、链路延迟、断点续传验证
配置全部完成之后,先别急着上线,做三次演练,每次都能发现至少一个问题。
第一次演练主备切换。停掉主节点的 KepServer 服务,记录事件日志里备机完成接管的时间戳,计算从服务停止到备机开始提供服务的总耗时。理论上就是心跳间隔乘判定次数加切换延时。如果实际耗时长得多,先查心跳网卡有没有被防火墙拦,再查备机是不是还在扫描生产网络上的其它设备,冗余通道被拖慢了。
第二次演练全链路延迟。在 PLC 里放一个每秒翻转的位,比如 M50.0,通过 DataLogger 写入 MySQL,然后在 MySQL 里查这条记录的 write_time 减去 PLC 翻转动作的时间,得到采集链路延迟。正常应该在 1 到 2 秒内,超过 5 秒说明触发方式或 ODBC 连接有问题。下发链路反过来验证:往 mes_order 插一条测试工单,看脚本多久把值写进 PLC,PLC 再置位握手信号,脚本再更新状态,整个过程应当小于轮询间隔加握手超时的总和。
第三次演练断点续传。把 MySQL 服务停掉两分钟,同时保持 PLC 数据在变化,然后恢复 MySQL,观察 DataLogger 是否把停库期间缓存的记录补写进去。补不上缓存或者丢记录,说明缓存配置或重试机制有问题,要趁上线前把数据补偿方案定下来,不要等真出了故障再去找逻辑漏洞。
我自己的习惯是每次做完演练,写一份带时间戳的交接记录,把主备切换耗时、延迟数值、失败项和处理方法都固定下来,下次再排查同类问题直接翻记录。产线数据系统不怕出问题,怕的是出问题时不知道怎么验证、不知道怎么回滚。这套东西跑顺之后,再回头看标题里的四个词,其实就是一条完整的数据链路:主备保证服务不停,双向读写保证数据流动,后台服务保证进程不死,地址填写保证数值不错。希望帮到你。
本文还有配套的精品资源,点击获取