ANDREW/
選單觀點
中文EN
← 回到文章庫

TECHNOLOGY / UPLINK FAILOVER

備援系統一切正常。只是不能上網。

Andrew Yuan · 技術實驗

健康:誰回答了,使用者就能上網嗎?

「備援系統正常嗎?」
「正常,兩條線的 Gateway 都 Ping 得到。」
「那為什麼大家不能上網?」
「這個……系統沒有檢查到那麼遠。」

這有點像客服電話接通了,接著請你等候四十分鐘。報表寫著:接聽率 100%。你要辦的事,還在等待音樂裡。

我做的 Uplinkstead,是一個 Linux IPv4 雙上行備援實驗。本文談的是需要明確啟用的 dual-DHCP 模式:兩個專用上行介面、一個路由式 LAN,各自取得與更新租約,再依證據選擇新流量的出口。靜態雙上行與單 DHCP 是另外的模式,不能混用操作假設。

Uplinkstead 概念插畫:兩條上行線路接到亮著綠燈的路由器,另一條線通往問號卡片;切換不等於服務已恢復。
概念插畫:呈現「系統正常」與「使用者連得上」的差距,並非部署拓樸圖。

Gateway 回覆,只能回答附近的一個問題。上游某處黑洞、轉送規則不對、回程走錯,使用者仍可能無法建立連線。因此,這個實驗把幾層證據分開:

窄螢幕可左右滑動表格,查看完整內容。

四種觀察,回答四個不同問題
觀察能支持的判斷仍不能推出
Gateway 可達本機到該閘道的受測路徑有回應。閘道以外可達,或使用者服務正常。
綁定上行的 TLS 探測指定介面、來源位址與 mark 下,配置的目標通過 TLS 檢查與設定的 quorum。所有網際網路目標可達,或 HTTP 業務結果正確。
新 LAN TLS 連線受測 LAN 用戶的新連線,經預期出口到達指定 TLS 目標。每個應用程式、DNS 或其他未測目的地都已恢復。
既有流量延續必須另外觀察原有連線是否持續。新連線成功,就代表舊 NAT 映射與工作階段不中斷。

Uplinkstead 的探測綁定裝置、來源與 mark,避免測 A 線時偷偷借用 B 線或主路由預設出口。它依配置目標的成功門檻判定健康;這是指定路徑的可達性證據,不是 HTTP 業務驗證。受控環境的三個目標是同一台伺服器的三個連接埠,也不是三個獨立故障範圍。

新鮮度:這份健康證據還屬於現在嗎?

探測通過之後,下一個問題不是「能不能存起來」,而是「何時不能再用」。同一條線的租約更新、位址或 Gateway 改變,以及租約失效,都會使原本的健康證據失效。Writer 重新啟動,也不能拿上一次的綠燈直接恢復轉送。

換了供應商,卻拿上一家供應商的稽核報告說「品質已確認」,文件很齊,對象不對。網路狀態也有同樣的問題。

因此,健康不只是布林值,還要對得上目前租約、執行世代與有效期限。新 Writer 必須重新取得可接受的租約與新健康證據,才有權恢復流量;舊請求也不能因為遲到,就重新取得已退休的權限。

這有可用性的代價。一般續租即使看起來沒有改變位址,仍需要重新證明健康,期間可能撤回不再有證據支持的路徑。這個設計選擇承認短暫未知,而不是讓過期證據繼續授權。它不表示對所有環境都最合適;可接受的中斷、續租節奏與重新探測成本,仍要由部署情境決定。

切換:多切幾次,真的比較有韌性嗎?

遇到抖動,立刻切線看似積極;訊號一恢復,又立刻切回,也很容易讓兩條線輪流打斷工作。

就像案子在 A、B 部門之間轉了三次,事情還沒辦完。主管看了流程圖:「我們反應很快,很 Agile。」使用者只想知道,現在到底找誰。

Uplinkstead 用成功/失敗輪次、候選等待與撤回寬限,避免一次結果就決定所有事。已切到健康備援後,原主線恢復也不會自動搶回選擇。這種 sticky failover 讓「目前選中的路徑仍然健康」優先於「名義上的主線回來了」。

等待能減少反覆切換,也會延後對真故障的反應;黏住備援能降低擾動,也可能讓流量繼續使用成本較高或容量較小的線路。這些都是策略取捨,不能從一次測試產生自動適用的最佳秒數。

另外還有持久化的切換預算與 latch。超過限制後,系統可能刻意不再進行另一次切換,直到有權限的人處理;這會限制故障連鎖,也可能使可用性繼續受損。重啟或 resume 不能清除 latch。初次選擇會計入預算,一般續租本身不算跨上行切換。

切換的承諾也要說清楚:這裡處理的是新流量選擇。換出口時,舊 NAT 映射與既有連線可能中斷;恢復一個新 TLS 連線,不會把進行到一半的下載或工作階段搬到另一條線。

權限:誰提議,誰有權改路?

架構上,沒有 Linux capabilities 的 Worker 提出選擇建議;有網路權限的 Writer 才能執行,並自行重查租約、健康、權限 token、等待條件、預算與鎖定狀態。Worker 說「切到 B」,不是足以修改路由的證據。

這個界線縮小了提案端可直接做的事,但 Writer、DHCP client 與擷取路徑仍是受信任的特權元件。不能把程序分離寫成「即使 root Writer 被入侵也能隔離」。

操作語意也有差異:pause 可保留仍然安全的已選路徑,同時繼續安全撤回;stop 會撤回配置與選擇,保留避免借用主預設出口的防護。服務崩潰後,舊核心狀態可能留到監督與清理執行;核心錯誤或不明的所有權也可能阻止撤回。狀態頁有答案,不等於所有底層動作都一定成功。

證據:這次保留下來的是什麼?

以下數字來自既有 closure run ab44c08f9940277e,不是為這篇文章重新跑的實驗。macOS 與 Linux 各通過 295 項 Portable Tests,測試識別與來源相同、沒有跳過。Linux 的整合路徑使用安裝後的 wheel、核對模組與配套檔案雜湊,執行隨附 systemd units,以命名空間隔離受測網路。

六次作用中上行黑洞/恢復循環,都觀察到新 LAN TLS 連線經預期的另一條路徑成功;移除故障後,恢復的線路沒有搶回健康的已選出口。初次選擇加上六次切換,共留下七筆預算計費;中間的自然續租沒有增加跨上行計費。

資源系列有 268 個樣本,跨 540.006 秒,約九分鐘;要求同一個 Writer、Worker 與兩個 DHCP client 身分持續存在,正式 stop/start 是採樣結束後另外做的操作。五分鐘尾段的 Writer RSS 中位數仍增加 176 KiB。它通過預先聲明的短期門檻,但不是零成長、無記憶體洩漏或效能改善證明,也沒有提供吞吐量、延遲或中斷 SLO。

失敗紀錄同樣重要。每個 DHCP session 的歷史上限是 64 個不同 REQUEST transaction ID,沒有得到回覆的嘗試也會占用。較早的快速續租實驗碰到上限,必須重建 client session 並取得新健康,未通過「同一組 client」的資源檢查。最終系列在 120 秒租約下使用受控 T1:A 20 秒、B 15 秒,讓這段觀察保持在上限內。

這沒有修復或驗證長期 rollover;重新取得 session 與健康的過程可能中斷流量。探測排程與續租節奏都曾改變,因此也不能把不同嘗試的 RSS 差異歸因於單一修改。保留失敗,比把最後一次綠燈寫成「長期穩定」更有用。

範圍:受控驗證離實際部署還有多遠?

這些網路命名空間共用同一台 Linux VM 的核心,不是兩家實體 ISP 的獨立故障驗證。任意 DHCP 伺服器相容性、突然斷電、開機零空窗與長期容量都仍未經驗證。較早的正常 VM reboot 證據有自己的來源與 25 秒 fixture 啟動計時器;它是另一份歷史紀錄,不是本次 closure 的重測,也不是產品開機保護或恢復時間保證。

這也不是安裝後就能接管整台路由器的套裝。轉送、NAT、回程、反向路徑設定與介面就緒,都有外部部署前提。配置範例裡加速的時間值是測試條件,不是正式環境的建議值。

本文把保留的量測、目前實作的契約,以及用來說明的假想管理對話分開。這是一個有邊界的系統實驗;沒有宣稱實際客戶部署經驗,也沒有把提案或笑話當成正式環境保證。

接手:綠燈之外,團隊要先決定什麼?

技術可以決定某份證據是否仍有效,但「要恢復哪種工作、能承受多少中斷、誰接手」需要團隊先回答。要是 latch 已鎖住、狀態仍未知,只有一句「請人工處理」並不算交接。

備援的價值,不只是讓狀態從紅色變綠色。它還需要讓新工作真的有機會完成,讓舊工作可能中斷的代價被理解,並在自動化必須停下時,留下有人能執行的下一步。

來源與重現

來源文件固定於公版 commit f1a0ecf;保留的驗證紀錄包含各自的來源指紋與重現條件。

分享這篇