<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Recovery-Order on Tarragon</title><link>https://tarrragon.github.io/blog/tags/recovery-order/</link><description>Recent content in Recovery-Order on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 03 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/recovery-order/index.xml" rel="self" type="application/rss+xml"/><item><title>Failover 機制</title><link>https://tarrragon.github.io/blog/devops/06-high-availability/failover-mechanism/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/devops/06-high-availability/failover-mechanism/</guid><description>&lt;p>單點掛了，怎麼自動切到替代路徑？failover 機制把這件事拆成三個環節：怎麼知道要切（觸發）、切到哪與怎麼切（切換）、以及事後怎麼把系統收回穩態（恢復順序）。三者裡最危險的往往是恢復順序、而不是切換本身——切換做對了、恢復動作卻因為依賴一個還沒恢復的元件而卡死，把一次可控的故障拖成漫長的中斷。&lt;/p>
&lt;h2 id="觸發探活是-failover-的前提">觸發：探活是 failover 的前提&lt;/h2>
&lt;p>Failover 的觸發條件是探活——健康檢查判定某個節點不健康，才觸發切換。這是 &lt;a href="https://tarrragon.github.io/blog/devops/04-service-health/" data-link-title="模組四：服務探活與自動恢復" data-link-desc="服務掛了怎麼自動發現和恢復 — health check 設計、liveness vs readiness、systemd watchdog、process supervisor">模組四 服務探活&lt;/a> 的主題：沒有可靠的探活，failover 要嘛切得太晚（壞了很久才發現）、要嘛切得太急（一次抖動就誤判、觸發不必要的 failover）。自動 failover 快、但依賴探活的準確度，探活抖動會讓它反覆切換；手動 failover 慢、但多了一層人的判斷，適合切換代價高、誤切損失大的場景。選自動還是手動，取決於「切錯的代價」跟「切慢的代價」哪個大。&lt;/p>
&lt;h2 id="切換先劃定故障域否則恢復動作變放大器">切換：先劃定故障域，否則恢復動作變放大器&lt;/h2>
&lt;p>切換之前要先知道這次故障的邊界到哪——它最多會影響到哪個範圍。這個故障域（fault domain）如果沒有預先定義，恢復動作本身可能變成新的放大器：以為只是切一個節點、實際上牽動了跨區的共享路徑，切換的動作反而把故障擴散得更廣。跨區的高可用尤其要先劃清楚「這個故障最多蔓延到哪裡」，才知道 failover 要切多大範圍、以及切換不會誤傷到本來健康的部分。&lt;/p>
&lt;p>切換要盯三個訊號判斷它有沒有失控：跨區的錯誤是不是在越界擴散、failover 的完成進度有沒有在收斂、以及共享的依賴有沒有變成瓶頸。這三個訊號來自大型平台跨區故障的實戰——它們揭露一件事：大規模系統真正的擴散面在跨區共享的相依路徑、不在單點失效本身，單點失效只是觸發點。&lt;/p>
&lt;h2 id="恢復順序循環等待是最大的風險">恢復順序：循環等待是最大的風險&lt;/h2>
&lt;p>恢復順序決定整體恢復時間，而它最大的風險是循環等待。系統大致分兩層：控制面是管理與調度那一層（下發設定、決定路由、協調誰接手），資料面是實際處理請求流量那一層。當控制面與資料面共用某條路徑、而恢復動作又依賴一個尚未恢復的控制面服務時，恢復就卡在一個環裡——要恢復 A 得先有 B、要恢復 B 得先有 A。有大型平台在一次全區故障裡就撞到這個：恢復需要的工具本身依賴了已經故障的系統（網路路由、DNS、遠端存取），結果連「開始恢復」這個動作都做不了，故障時間被恢復工具的循環依賴大幅拉長。&lt;/p>
&lt;p>所以恢復要分批、不能同時恢復所有路徑。同時把多條路徑一起拉起來，可能在剛恢復、還很脆弱的依賴上引發回源放大（原本被快取或前端擋掉的請求，因為那層還沒回來、全部同時回打源頭）或連鎖過載，把一次可控的恢復變成第二次故障。可靠的做法是依事故的時間線與既定的 runbook 安排恢復批次，每一批先驗證 baseline 穩定了、再進下一批。恢復順序的設計原則因此有兩條：讓恢復路徑不依賴任何可能故障的控制面（恢復工具要能在控制面掛掉時獨立運作）、以及分批推進而非一次全開。&lt;/p>
&lt;h2 id="資料一致性rollback-還是-roll-forward">資料一致性：rollback 還是 roll-forward&lt;/h2>
&lt;p>Failover 或變更失敗時，除了切走流量，還有一個資料層的決策：退回舊版（rollback）還是往前修（roll-forward）。判斷取決於這個變更可不可逆、以及新資料是否已經依賴了新結構。可逆的（schema 向下相容、feature flag 可關、路由可切回）用 rollback，它通常比 roll-forward 快收斂，因為退回的是一個已經被驗證過的行為；不可逆的（新版已經寫入了不能回退的資料）只能 roll-forward。還有一種混合：先 rollback 止血、穩定後再 roll-forward 修復。&lt;/p>
&lt;p>這個判斷有一個容易漏的層次：rollback 的安全性不只看部署層、還要看資料語義層。一個交易系統的 rollback，要同時處理 schema 相容跟冪等重播——退回程式版本容易，但那段期間寫入的資料若跟新版本的語義綁定，光退版會留下不一致。判斷 rollback 還是 roll-forward，五個軸要一起看：schema 相容性、資料狀態、修復時間、feature flag、下游依賴。&lt;/p>
&lt;h2 id="依賴隔離切斷共享相依的放大">依賴隔離：切斷共享相依的放大&lt;/h2>
&lt;p>Failover 能不能乾淨切換，很大程度取決於依賴有沒有被隔離。共享的相依路徑是故障放大的主要通道——一個依賴退化，透過共享路徑拖垮所有用到它的服務。隔離的做法是把不同的工作負載、不同的租戶關進各自的資源池，一個池的故障不外溢到別的池，這正是 &lt;a href="https://tarrragon.github.io/blog/devops/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">模組三 流量管控&lt;/a> 的 bulkhead 隔離搬到高可用場景。依賴隔離做得好，failover 只需要切掉受影響的那個隔離區，不必動到整個系統。&lt;/p>
&lt;h2 id="下一步路由">下一步路由&lt;/h2>
&lt;ul>
&lt;li>Failover 的觸發前提——探活怎麼做 → &lt;a href="https://tarrragon.github.io/blog/devops/04-service-health/" data-link-title="模組四：服務探活與自動恢復" data-link-desc="服務掛了怎麼自動發現和恢復 — health check 設計、liveness vs readiness、systemd watchdog、process supervisor">模組四 服務探活&lt;/a>&lt;/li>
&lt;li>冗餘準備好才有得切、切換對上層透明的前提 → &lt;a href="https://tarrragon.github.io/blog/devops/06-high-availability/redundancy-patterns/" data-link-title="冗餘設計模式" data-link-desc="在 active-passive、active-active、multi-region 之間選冗餘模式時，用資料同步方式與 standby 是否服務流量來區分，並知道冗餘不等於備份">冗餘設計模式&lt;/a>&lt;/li>
&lt;li>恢復順序、restore 驗證與演練節奏 → &lt;a href="https://tarrragon.github.io/blog/devops/06-high-availability/disaster-recovery/" data-link-title="Disaster recovery 策略" data-link-desc="設計災難復原時，先確認恢復路徑走得通再談 RTO/RPO、用 restore drill 把估值變量值、以及知道恢復不是切回流量就結束">Disaster recovery 策略&lt;/a>&lt;/li>
&lt;li>Bulkhead 隔離怎麼切斷共享相依 → &lt;a href="https://tarrragon.github.io/blog/devops/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">模組三 流量管控&lt;/a>&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>單點掛了，怎麼自動切到替代路徑？failover 機制把這件事拆成三個環節：怎麼知道要切（觸發）、切到哪與怎麼切（切換）、以及事後怎麼把系統收回穩態（恢復順序）。三者裡最危險的往往是恢復順序、而不是切換本身——切換做對了、恢復動作卻因為依賴一個還沒恢復的元件而卡死，把一次可控的故障拖成漫長的中斷。</p>
<h2 id="觸發探活是-failover-的前提">觸發：探活是 failover 的前提</h2>
<p>Failover 的觸發條件是探活——健康檢查判定某個節點不健康，才觸發切換。這是 <a href="/blog/devops/04-service-health/" data-link-title="模組四：服務探活與自動恢復" data-link-desc="服務掛了怎麼自動發現和恢復 — health check 設計、liveness vs readiness、systemd watchdog、process supervisor">模組四 服務探活</a> 的主題：沒有可靠的探活，failover 要嘛切得太晚（壞了很久才發現）、要嘛切得太急（一次抖動就誤判、觸發不必要的 failover）。自動 failover 快、但依賴探活的準確度，探活抖動會讓它反覆切換；手動 failover 慢、但多了一層人的判斷，適合切換代價高、誤切損失大的場景。選自動還是手動，取決於「切錯的代價」跟「切慢的代價」哪個大。</p>
<h2 id="切換先劃定故障域否則恢復動作變放大器">切換：先劃定故障域，否則恢復動作變放大器</h2>
<p>切換之前要先知道這次故障的邊界到哪——它最多會影響到哪個範圍。這個故障域（fault domain）如果沒有預先定義，恢復動作本身可能變成新的放大器：以為只是切一個節點、實際上牽動了跨區的共享路徑，切換的動作反而把故障擴散得更廣。跨區的高可用尤其要先劃清楚「這個故障最多蔓延到哪裡」，才知道 failover 要切多大範圍、以及切換不會誤傷到本來健康的部分。</p>
<p>切換要盯三個訊號判斷它有沒有失控：跨區的錯誤是不是在越界擴散、failover 的完成進度有沒有在收斂、以及共享的依賴有沒有變成瓶頸。這三個訊號來自大型平台跨區故障的實戰——它們揭露一件事：大規模系統真正的擴散面在跨區共享的相依路徑、不在單點失效本身，單點失效只是觸發點。</p>
<h2 id="恢復順序循環等待是最大的風險">恢復順序：循環等待是最大的風險</h2>
<p>恢復順序決定整體恢復時間，而它最大的風險是循環等待。系統大致分兩層：控制面是管理與調度那一層（下發設定、決定路由、協調誰接手），資料面是實際處理請求流量那一層。當控制面與資料面共用某條路徑、而恢復動作又依賴一個尚未恢復的控制面服務時，恢復就卡在一個環裡——要恢復 A 得先有 B、要恢復 B 得先有 A。有大型平台在一次全區故障裡就撞到這個：恢復需要的工具本身依賴了已經故障的系統（網路路由、DNS、遠端存取），結果連「開始恢復」這個動作都做不了，故障時間被恢復工具的循環依賴大幅拉長。</p>
<p>所以恢復要分批、不能同時恢復所有路徑。同時把多條路徑一起拉起來，可能在剛恢復、還很脆弱的依賴上引發回源放大（原本被快取或前端擋掉的請求，因為那層還沒回來、全部同時回打源頭）或連鎖過載，把一次可控的恢復變成第二次故障。可靠的做法是依事故的時間線與既定的 runbook 安排恢復批次，每一批先驗證 baseline 穩定了、再進下一批。恢復順序的設計原則因此有兩條：讓恢復路徑不依賴任何可能故障的控制面（恢復工具要能在控制面掛掉時獨立運作）、以及分批推進而非一次全開。</p>
<h2 id="資料一致性rollback-還是-roll-forward">資料一致性：rollback 還是 roll-forward</h2>
<p>Failover 或變更失敗時，除了切走流量，還有一個資料層的決策：退回舊版（rollback）還是往前修（roll-forward）。判斷取決於這個變更可不可逆、以及新資料是否已經依賴了新結構。可逆的（schema 向下相容、feature flag 可關、路由可切回）用 rollback，它通常比 roll-forward 快收斂，因為退回的是一個已經被驗證過的行為；不可逆的（新版已經寫入了不能回退的資料）只能 roll-forward。還有一種混合：先 rollback 止血、穩定後再 roll-forward 修復。</p>
<p>這個判斷有一個容易漏的層次：rollback 的安全性不只看部署層、還要看資料語義層。一個交易系統的 rollback，要同時處理 schema 相容跟冪等重播——退回程式版本容易，但那段期間寫入的資料若跟新版本的語義綁定，光退版會留下不一致。判斷 rollback 還是 roll-forward，五個軸要一起看：schema 相容性、資料狀態、修復時間、feature flag、下游依賴。</p>
<h2 id="依賴隔離切斷共享相依的放大">依賴隔離：切斷共享相依的放大</h2>
<p>Failover 能不能乾淨切換，很大程度取決於依賴有沒有被隔離。共享的相依路徑是故障放大的主要通道——一個依賴退化，透過共享路徑拖垮所有用到它的服務。隔離的做法是把不同的工作負載、不同的租戶關進各自的資源池，一個池的故障不外溢到別的池，這正是 <a href="/blog/devops/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">模組三 流量管控</a> 的 bulkhead 隔離搬到高可用場景。依賴隔離做得好，failover 只需要切掉受影響的那個隔離區，不必動到整個系統。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>Failover 的觸發前提——探活怎麼做 → <a href="/blog/devops/04-service-health/" data-link-title="模組四：服務探活與自動恢復" data-link-desc="服務掛了怎麼自動發現和恢復 — health check 設計、liveness vs readiness、systemd watchdog、process supervisor">模組四 服務探活</a></li>
<li>冗餘準備好才有得切、切換對上層透明的前提 → <a href="/blog/devops/06-high-availability/redundancy-patterns/" data-link-title="冗餘設計模式" data-link-desc="在 active-passive、active-active、multi-region 之間選冗餘模式時，用資料同步方式與 standby 是否服務流量來區分，並知道冗餘不等於備份">冗餘設計模式</a></li>
<li>恢復順序、restore 驗證與演練節奏 → <a href="/blog/devops/06-high-availability/disaster-recovery/" data-link-title="Disaster recovery 策略" data-link-desc="設計災難復原時，先確認恢復路徑走得通再談 RTO/RPO、用 restore drill 把估值變量值、以及知道恢復不是切回流量就結束">Disaster recovery 策略</a></li>
<li>Bulkhead 隔離怎麼切斷共享相依 → <a href="/blog/devops/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">模組三 流量管控</a></li>
</ul>
]]></content:encoded></item></channel></rss>