當網線被踢掉 — xGrid 的 Hub-Spoke 拓撲與斷線復原
兩台裝置,一條網線,零台雲端伺服器。當這條網線被踢掉時,兩台機器各自獨立運作。接回來時,自動同步。
先講一個你已經知道的 Hub-Spoke
你可能沒聽過「Hub-Spoke 拓撲」這個詞,但你每天都在使用它。
打開任何一張航空公司的航線圖。你會看到幾個巨大的節點——桃園、成田、新加坡樟宜——從這些節點輻射出密密麻麻的航線,連接到幾十個較小的城市。大節點是 Hub(樞紐),小城市是 Spoke(輻條)。
點對點(上)vs Hub-Spoke(下):透過中心節點轉發,大幅減少連線數量。圖片來源:Wikipedia(公有領域)
為什麼航空公司要這樣設計?因為如果每個城市都直飛其他城市,30 個城市需要 435 條航線。但如果所有城市都先飛到 Hub,再從 Hub 轉飛,只需要 30 條航線。Hub 是協調者,集中處理調度、轉機、和資源分配。
物流也一樣。FedEx 的全球運轉中心在曼菲斯。你從台北寄一個包裹到高雄,它可能先飛到曼菲斯再飛回來——聽起來荒謬,但集中分揀比點對點轉運更有效率。
這個模式在資訊系統中也很常見:一個中心節點協調多個邊緣節點。資料在 Hub 集中,Spoke 負責第一線操作。
但傳統 Hub-Spoke 有一個致命假設:Hub 永遠在線。
航班可以等 Hub 機場開放。包裹可以等分揀中心處理。但在災難現場,如果 Hub 掛了,病人不能等。
xGrid 的 Hub-Spoke 做了一個關鍵修改:每個 Spoke 都是完整的系統,不只是終端。 Hub 掛了?Spoke 繼續運作。網線斷了?兩邊各自獨立。接回來?自動同步。
實際部署:兩台裝置,一條網線
xGrid 的部署架構:
┌─────────────────────┐
│ Hub(主站) │
│ WiFi 熱點 │
│ 臨床 + 資源系統 │
│ 有外部網路 ✓ │
└──────────┬──────────┘
│ 乙太網線
┌──────────┴──────────┐
│ Spoke(衛星站) │
│ 臨床 + 資源系統 │
│ 無外部網路 ✗ │
└─────────────────────┘
Hub 是主站,開著 WiFi 熱點,護理師的手機連上它工作。Spoke 是衛星站,只透過一條乙太網線連到 Hub,沒有任何外部網路存取。
這條網線被踢掉的瞬間,Spoke 變成一座孤島。
但它不會停止運作。
斷線不是故障,是預期狀態
傳統的系統把網路斷線當成「故障」來處理——偵測到斷線 → 觸發告警 → 等待恢復。
xGrid 把斷線當成「正常」來設計。每台裝置都是完整的系統——有自己的臨床系統、自己的資源系統、自己的資料庫。斷線只是暫時失去了同步能力,不是失去了運作能力。
這就是 xGrid 版 Hub-Spoke 跟航空版最大的差異:Spoke 不是等待 Hub 指令的終端,而是能獨立運作的完整系統。Hub 提供的是協調,不是能力。
三階段雙向同步
當兩台裝置之間的網線接著的時候,它們自動進行雙向同步:
第一階段 — 健康檢查
Hub 先確認 Spoke 是否在線。如果 30 秒內沒回應,跳過這次同步。同時檢測兩台裝置的時鐘是否一致——如果時間差超過 30 秒,拒絕同步,避免時間戳混亂。
第二階段 — 臨床資料推送(Hub → Spoke)
Hub 把臨床事件推給 Spoke:病患資料、掛號、處方、生命徵象、交班紀錄。臨床系統是這些資料的權威來源。
第三階段 — 資源資料回收(Spoke → Hub)
Hub 從 Spoke 拉回資源事件:庫存異動、血庫操作、手術記錄、藥品發放。資源系統是這些資料的權威來源。
每次同步只傳上次同步之後的變更,不是整個資料庫。快速、省頻寬。
六種衝突解決策略
兩台裝置在斷線期間各自修改了同一筆資料,接回來時怎麼辦?
答案取決於資料的性質:
| 策略 | 適用資料 | 邏輯 |
|---|---|---|
| 直接追加 | 生命徵象、交班紀錄、發放紀錄 | 不可修改的紀錄,兩邊都保留 |
| 較新的勝 | 病患基本資料 | 比較修改時間,取最新版 |
| 主站優先 | 掛號、處方、手術紀錄 | Hub 是臨床資料的權威來源 |
| 數量相加 | 庫存數量 | 兩邊的消耗各自累加 |
| 人工處理 | 血袋、管制藥品 | 不自動解決,等人確認 |
| 現場優先 | 設備狀態 | 在現場的操作者說了算 |
最值得注意的是人工處理。血袋和管制藥品的衝突不允許自動解決——因為錯誤的代價太高。一袋血被兩個站同時標記為「已發放」?這不是可以用時間戳解決的問題。系統會標記衝突,等待負責人員確認。
數量相加也很有意思:主站消耗了 5 個紗布,衛星站消耗了 3 個。正確答案不是「以較新的為準」(那會遺失其中一邊的消耗),而是 5 + 3 = 8 個被消耗。
自動備援切換
Hub 每 30 秒對 Spoke 做一次健康檢查。如果連續三次失敗(共 90 秒無回應),系統判定 Spoke 失聯。
如果有設定備援 Hub,系統自動切換到備援。但切回主 Hub 必須手動觸發——在災難現場,自動切換可能造成不可預測的狀態變動。操作者需要確認主 Hub 確實穩定了,才手動切回。
站點合併:撤離時的資料整合
當一個站被迫撤離,它的資料需要合併到存活的站。
四種合併模式:
- 完整合併:兩站資料全部合入目標站
- 選擇性合併:只合併選定的物資類別
- 備份還原:從外接儲存裝置還原
- 緊急關站:保存資料後關閉站點
每次合併都完整記錄:從哪個站、合了多少物資、多少血袋、多少設備、多少手術紀錄。在災難結束後,你需要能回答「那個站撤離時,東西都去了哪裡?」
軟體更新
Hub 有外部網路,可以接收遠端推送的更新。Spoke 沒有——它的更新由 Hub 透過內部網路轉發。
整個過程是受控的。更新不會自動套用——操作者確認後才會部署到各站點。在災難現場,穩定性永遠優先於新功能。
設計哲學:為斷線而生
大多數系統的設計前提是「網路是可靠的」,然後為不可靠的情況做例外處理。
xGrid 的設計前提是「網路是不可靠的」,然後為可靠的情況做優化。
這個顛倒導致了完全不同的設計決策:
- 每個節點都是完整系統(不是只能顯示畫面的終端機)
- 同步是定期的批次操作(不是即時的持續連線)
- 衝突解決是預設行為(不是例外處理)
- 人工判斷是某些情況的正確答案(不是需要消除的缺陷)
網線被踢掉不是故障。它只是兩個獨立系統之間的一次暫別。