🎯 什麼情境該想到我

當你「要把新版推上生產,但想先在一小群人身上驗證沒問題,再一級一級擴大範圍」的時候。

⚙️ 怎麼用(步驟 / 公式)

意圖:把發布流程自動化成「逐級晉升到越來越大、越來越關鍵的環境」,每一級都先確認程式如設計般運作,才往下一級推。

做法要點:

  • 名稱來自礦工把金絲雀關在籠子裡帶進礦坑,用來提早偵測一氧化碳——毒氣先殺死金絲雀,礦工才知道要撤離。
  • 發布時監控每一級環境裡軟體的表現:看起來不對就 roll back,沒問題才部署到下一級環境。
  • 這是藍綠部署的變體,用自動化進一步提升安全性與縮短部署前置時間,代價是額外的複雜度。

Facebook 為此模式建立的三群組結構(書中圖 21):

  • A1 群組:只服務內部員工的生產伺服器。
  • A2 群組:只服務一小部分客戶的生產伺服器,在**滿足特定驗收標準(自動或人工皆可)**後才部署。
  • A3 群組:其餘所有生產伺服器,在 A2 叢集上跑的軟體滿足特定驗收標準之後才部署。

叢集免疫系統(Cluster Immune System)——金絲雀的延伸:

  • 做法是把生產監控系統與發布流程串接起來,當生產系統面向使用者的表現偏離預先定義的期望範圍時,自動 roll back 程式碼。
  • 書中給的具體判準例子:新使用者的轉換率跌到歷史常態水準(15%–20%)以下時。注意這裡的 15%–20% 是轉換率本身的歷史正常值(平常約有 15%–20% 的新使用者會轉換),不是「比平常下跌 15%–20%」;也就是說,若新版上線後新使用者轉換率掉到例如 12%,低於 15% 的下緣,就觸發自動 roll back。
  • 兩個顯著好處:
    1. 防住自動化測試很難抓到的缺陷,例如某個 CSS 變更害關鍵頁面元素變成看不見;
    2. 縮短偵測與回應「效能被自己的變更弄壞」所需的時間。

原文:「The canary release pattern automates the release process of promoting to」(L6652,接 L6653–6654「successively larger and more critical environments as we confirm that the code is operating as designed.」)

原文:「rates for new users drops below our historical norms of 15%–20%.」(L6687)

實際怎麼逐級放量(推測:書中只給 A1/A2/A3 三群組與「滿足驗收標準才往下推」,以下切流量、階段比例、觀察窗與判準為一般業界做法,數字為自寫範例)

  1. 選切流量的方式:
    • 按伺服器群組切(書中 Facebook 的做法):新版只部署到某一群機器,負載平衡器照常分流——新版拿到的流量比例 ≈ 該群機器佔總機器的比例(例:100 台裡 2 台跑新版 ≈ 2%)。
    • 按負載平衡器權重切:新舊版各一組 upstream,用權重控制比例(例:Nginx upstream 的 weight=1 對 weight=99,或 service mesh 的路由權重 1/99)。好處是比例跟機器數量脫鉤,可以調到 1% 以下。
    • 建議以使用者為單位黏住(sticky,例如用 user ID 雜湊分組):同一個人這次看到新版、下次又看到舊版,既讓體驗錯亂,也讓指標混在一起算不準。
  2. 排定階段比例:例如 內部員工(A1)→ 1% → 5% → 25% → 50% → 100%。前幾級放得慢、後面放得快——因為最大的風險在「第一次碰到真實流量」。
  3. 每一級設觀察窗:例如每級至少 30 分鐘,且至少涵蓋一次該服務的流量尖峰;涉及每日批次或排程工作的變更,觀察窗要拉長到跑過一輪。
  4. 事先寫死晉升/退回條件,拿新版跟「同時段的舊版」比(不是跟昨天比):
    • 錯誤率:新版 5xx 比例 ≤ 舊版 + 0.1 個百分點;
    • 延遲:新版 p99 ≤ 舊版 p99 × 1.1;
    • 業務指標:新使用者轉換率不低於歷史常態下緣(呼應書中 15% 的例子);
    • 任一條違反 → 自動 roll back(這就是書中的叢集免疫系統);全部通過且觀察窗結束 → 自動晉升下一級。

🧪 我實際套用的紀錄

  • (待填)

⚠️ 注意 / 什麼時候不適用

  • 相對於藍綠部署,這個模式多了自動化與複雜度的代價,書中明白點出這是 trade-off。
  • 叢集免疫系統要能運作,前提是你已經有面向使用者的生產遙測與預先定義好的期望範圍——沒有基準線就沒有自動 roll back。
  • 與藍綠部署一樣屬於 environment-based release pattern,通常不必改應用程式碼,但也管不到「單一功能」的粒度。
  • 新舊版本會同時在生產環境跑——資料庫必須同時相容兩版:書中註腳明說金絲雀發布「需要在生產環境同時跑多個版本」,而每多一個版本就多一份管理複雜度,所以版本數要壓到最少,並且「可能需要用到前面講的 expand/contract 資料庫模式」。實際意義是:在放量期間,新版寫進去的資料舊版要讀得懂、舊版寫的資料新版也要讀得懂。做法(expand/contract,見藍綠部署):先只加不改(加新欄位、新表),等 100% 都切到新版且確定不退回,再另一次發布刪掉舊欄位。反例(推測):新版一上就把 name 拆成 first_name/last_name 並刪掉 name——此時 95% 流量還在舊版,舊版一讀就爆;而且一旦要 roll back,舊版也回不去了。
  • 金絲雀樣本太小,統計上看不出退步(推測,數字為自寫範例):假設新使用者轉換率常態是 15%,1% 階段在觀察窗內只分到 200 位新使用者。預期轉換 30 人,標準差 = √(200 × 0.15 × 0.85) ≈ 5.05,95% 區間約 30 ± 10 人,換算轉換率約 10%–20%——也就是說,就算新版真的把轉換率從 15% 打到 12%(相對掉 20%),在這個樣本量下也跟正常波動分不出來。粗估要可靠偵測 15% → 12%(雙尾 95% 信心、80% 檢定力),每組大約需要 n ≈ (1.96 + 0.84)² × (0.15×0.85 + 0.12×0.88) ÷ 0.03² ≈ 2,000 人。對策:小比例階段只拿來抓「爆炸級」問題(錯誤率、當機、延遲),業務指標類的判準要等放到夠大的比例、或把觀察窗拉長累積到足夠樣本再判;低流量服務的金絲雀,業務指標判準基本上不可靠。

🔗 相關工具