← 所有文章

雙閘道主備切換與事件去重設計

· 站長

以主機50後失聯、備機48起補送的事件表,拆解唯一主站權、fencing、跨閘道去重、缺口與晚到資料。

把可用性拆成四個問題

加第二台閘道之前,先說清楚要備援的是哪一段。網路能連上,不代表只有一個主站會操作設備;備機取得資料,也不代表歷史庫不會重複;畫面有數值,更不代表切換期間沒有缺口。把主站所有權、資料送達、事件去重與品質標記分開設計,才能在故障時知道哪個能力真的接手。

問題 需要的證據 不能拿什麼代替
網路可用 路徑及服務健康檢查 只看Ping
主站所有權 產品支援的仲裁或隔離機制 只看對方心跳消失
資料去重 穩定事件識別與提交記錄 只比較數值一樣
資料完整性 來源序號、缺口與時間 只看備機目前上線

本篇採虛構來源S,其事件具有開機世代B7與遞增序號,兩台閘道A、B可取得同一批來源事件。事件識別為S、B7、sequence三欄,gatewayId只記搬運者。如果來源沒有事件序號而由兩台各自輪詢,兩筆相同數值可能是不同採樣,不能照搬本篇的同一事件去重規則。

同時備援讀取與命令寫入時,寫入權特別需要明確安排。兩台TCP客戶端可以連上同一設備,不表示兩個控制命令可任意交錯;兩個RTU主站共用同一條線也不能因叫作主備就自動避免碰撞。正式設計先查閘道、協調系統與設備實際支援的所有權能力。

主機在事件50後失聯的離線案例

假設來源S在B7世代產生事件48至53,主機A已把48、49、50提交到上游資料庫。A在50之後失聯,備機B保有從48開始的重送資料,取得經確認的主站權後依序補送48至53。消費端不能因送達者從A變B就把48至50當成新事件。

到達順序 搬運者 事件鍵 消費端結果
原先 A S/B7/48至50 已提交三筆
恢復1 B S/B7/48 重複,保留原事件
恢復2 B S/B7/49 重複,保留原事件
恢復3 B S/B7/50 重複,保留原事件
恢復4至6 B S/B7/51至53 新增三筆

完成後,正式事件表共有48至53六筆,搬運嘗試記錄則可以有九筆,因為重送本身也是診斷證據。把事件表與送達記錄分開,既不讓趨勢重複計數,也能知道備援曾補送哪些資料。若業務動作是累加產量,必須在同一持久化交易內完成去重判斷與累加,避免先累加後才發現重複。

另一個分支是A把50寫入資料庫,但確認回覆在網路中遺失。A或B稍後重送50,仍應命中同一事件鍵,不能再加一次。通訊確認、訊息代理確認與業務資料庫提交是不同邊界;收到其中一個ACK,不一定代表整條鏈每個動作都已完成。

失去心跳不等於舊主機停止

如果A、B彼此網路斷開,但A仍能連到PLC,B只憑收不到A心跳就取得寫入權,兩台可能同時運作。這就是需要仲裁及隔離舊主機的原因。心跳提供故障懷疑,不能單獨證明舊主機已失去設備存取能力;更快的心跳只能更快懷疑,不能補足所有權證據。

情境 危險或限制 預期設計行為
A程式停止 主機可能確實不再送出 由支援的接手機制確認
A與B斷網 兩台都可能看不到對方 不得各自宣稱唯一主機
A仍連設備 備機接手可能造成雙主 先確認舊權限已撤回或隔離
協調服務失聯 無法證明租約仍有效 依設計停止取得新控制權
A恢復 舊角色不再可信 重新加入並同步狀態

可採的機制取決於產品,例如原廠冗餘協調、外部仲裁或能真正阻止舊主機的fencing。若設計使用世代權杖,受控服務必須能拒絕舊權杖才有意義;只在兩台閘道日誌寫一個世代號,不會讓不支援的PLC自動拒絕舊命令。本文不發明PLC指令或仲裁API。

切換流程先確認故障條件,再取得新所有權,確認舊主機已被有效隔離,最後啟用需要所有權的輪詢或寫入。對只讀、多客戶端且設備允許的場景,可以有不同策略,但仍要估算額外負載與資料來源。不要把某種監控備援規則直接套到會啟動機械的命令通道。

缺口與晚到資料如何顯示

備機開始補送時,畫面應分開顯示目前資料與歷史補送。假設51的來源時間較早,卻在53之後才到,事件表可接受51補齊缺口,但即時值不能因此倒退成51。用來源世代與序號判定新舊,保留來源時間與接收時間;來源時鐘跳動時,單靠時間排序不足以判斷順序。

若只收到48、49、50、52、53,缺51就先標示缺口待確認。等待期間多久、來源是否可重取及何時宣告永久遺失,均由資料契約決定;不能把序號50的值複製成51再宣稱完整。斷線時保留最後值可以幫助診斷,但品質與最後有效時間必須一起提供。

離線驗收 輸入事件 完成後應看到
正常補送 B重送48至53 事件六筆,重複三筆有記錄
ACK遺失 已提交50再收到50 業務計數不再增加
缺口 收到50、52、53 51缺口明確列出
晚到 53後才到51 補歷史,當前值不倒退
來源重啟 S/B8/1 新世代事件,不能當B7重複

若來源序號會回繞,契約必須提供回繞辨識或足夠的世代欄位。若兩台閘道自行產生相同序號48,那只是兩個本機序號巧合,不足以表示同一來源事件。事件鍵選錯會造成兩種相反錯誤:該去重的被重算,或真正的新採樣被刪掉。

測試恢復時也要觀察補送速度。上游處理率若只夠新資料,就無法清掉舊佇列;應量出新增率、補送率與最舊待送年齡,依優先規則安排。備援切換成功與歷史資料補齊可以在不同時間完成,狀態畫面應各自顯示。

FAQ與產品能力限制

FAQ1:兩台有相同IP就是完整高可用嗎?不是。浮動IP只解決部分網路定位,仍需服務狀態、資料同步、唯一控制權、去重及缺口處理,各項都要有獨立驗收。

FAQ2:用gatewayId加sequence當唯一鍵可以嗎?如果A與B是在搬運同一來源事件,加入不同gatewayId反而使重送無法去重。若本來就是獨立採樣,則須保留不同來源身分,不能強行合併。先定義事件從哪裡產生。

FAQ3:MQTT QoS2能取代業務去重嗎?不能從協定交付語意推論兩個發送者、資料庫寫入及累加動作都只執行一次。跨閘道補送仍需穩定事件鍵與消費端提交規則。

FAQ4:主機回來就立刻切回嗎?先查原廠支援的同步與回切流程。舊主機可能有過期設定、未完成命令與待送資料,先確認角色和世代,避免恢復的主機重新搶控制權。

Ignition官方冗餘文件將歷史資料的Full與Partial模式分開,並說明主備網路故障可能造成重複資料;這是特定平台行為的例子,不是任意硬體閘道都有相同模式。本篇S/B7事件鍵與fencing要求是離線架構設計。

參考:Inductive Automation Ignition 8.3 Redundancy,主備同步與歷史資料處理模式。

參考:OASIS MQTT Version 5.0,QoS與會話交付範圍。

延伸閱讀


使用 PLC 工具箱 →