← 回文章列表

2026年6月11日

藍綠部署、金絲雀部署、Feature Toggle:三種降低上線風險的部署機制

部署策略DevOps藍綠部署金絲雀部署Feature ToggleSRE

三者要解決的共同問題

傳統的部署方式是把舊版本整個停掉、換上新版本,中間有一段停機時間,而且新版本一上線就要面對 100% 的流量——如果新版本有問題,影響的是所有使用者,發現問題後也只能匆忙回滾。

藍綠部署、金絲雀部署、Feature Toggle 都是想解決同一件事:把「上線」這個高風險動作,拆成更小、更可控、可以隨時喊停的步驟,差別在於它們各自在哪一層做這件事——藍綠部署換的是整套執行環境,金絲雀部署換的是流量比例,Feature Toggle 換的是應用程式裡的一段邏輯開關。

藍綠部署(Blue-Green Deployment)

運作方式:準備兩套一模一樣的正式環境,一套叫 Blue(目前正在服務的版本),一套叫 Green(要上線的新版本)。新版本先完整部署到 Green、做健康檢查與暖機,確認沒問題後,透過負載平衡器把流量整批切換到 Green;如果切換後發現問題,只要把路由切回 Blue 就能立即恢復。

藍綠部署示意圖:負載平衡器把流量整批指向 Blue 或 Green 其中一套環境

適合的情境:

  • 想要幾乎零停機時間的上線方式——切換是路由層面的操作,不是重啟服務
  • 想要「出事能立刻整批回滾」,而不是重新部署舊版本
  • 新舊版本之間不需要同時服務流量、資料相容性問題相對單純的情境

使用風險:

  • 雙倍資源成本:兩套環境要同時常駐(至少在切換過渡期),資源花費接近兩倍
  • 全有或全無,沒有漸進空間:切換是瞬間的,如果 Green 有邏輯性錯誤但沒被健康檢查攔下來,切換的當下就是 100% 的使用者受影響,沒有「先讓一小部分人試試看」的餘地
  • 資料庫相容性最麻煩:如果 Blue 跟 Green 共用同一個資料庫,切換瞬間、甚至切回去的那一刻,新舊版本都可能對同一份資料做讀寫,資料庫的 schema 變更必須同時讓新舊版本都能運作
  • 有狀態連線的處理:像 WebSocket 這種長連線,整批切換會讓連線瞬間中斷,需要額外設計優雅排空(Drain)或重連機制

金絲雀部署(Canary Deployment)

運作方式:新版本先只導入一小部分流量(例如 5%),跟舊版本同時上線、同時服務使用者,透過監控指標觀察新版本是否正常;指標健康就逐步擴大流量比例(5% → 25% → 50% → 100%),指標異常就立即把金絲雀流量退回 0%,全程只有一小部分使用者受到影響。

金絲雀部署示意圖:負載平衡器依比例把流量分給舊版本與金絲雀新版本,指標正常逐步擴大比例

適合的情境:

  • 想要用真實流量驗證新版本,而不是只靠測試環境或人工驗收
  • 使用者基數夠大,切出 5% 的流量仍然是有代表性的樣本
  • 團隊已經有一定的可觀測性基礎(延遲、錯誤率等關鍵指標的監控),能在流量還很小的時候就判斷「這個版本健不健康」——如果團隊已經定義了 SLO,金絲雀期間消耗掉的錯誤預算,本身就是一個很自然的自動回滾依據

使用風險:

  • 新舊版本必須同時服務、同時讀寫同一份資料:這比藍綠部署的相容性要求更長時間——只要金絲雀流量還沒到 100%,新舊版本就會同時存在一段時間,新版本寫入的資料格式,舊版本(還在服務剩餘流量)也必須看得懂,反之亦然
  • 流量分配要有代表性:如果分流方式設計不好(例如剛好把同一個地區、同一種裝置的使用者導進金絲雀),5% 的樣本可能無法代表真實的流量特性,觀察到的指標就沒有意義
  • 需要自動化的判斷與回滾機制:金絲雀的意義在於「小範圍先試」,如果沒有自動化告警、自動回滾,全靠人工盯著儀表板看,實際上就退化成手動、慢半拍的藍綠切換
  • 路由層要求更高:需要能依比例動態分流的基礎設施(Kubernetes 搭配 Service Mesh、或雲端負載平衡器的加權路由),比藍綠部署單純的「切全部」複雜

Feature Toggle(功能開關)

運作方式:在程式碼裡用一個開關(Flag)包住新功能,讓「部署」跟「發布」變成兩件互相獨立的事——新程式碼可以先完整部署上線,但功能保持關閉狀態,之後只要透過設定或後台切換開關,就能立即讓功能生效,不需要重新部署。

Feature Toggle 示意圖:同一個應用程式版本內部依 Feature Flag 狀態走不同邏輯分支

Feature Toggle 常見可以再分幾種用途:

  • Release Toggle(釋出開關):短期使用,功能穩定全開之後就該把開關和舊邏輯一起移除
  • Experiment Toggle(實驗開關):用來做 A/B 測試,不同使用者群組看到不同邏輯
  • Ops Toggle(維運開關):緊急時可以手動關閉某個功能或繞過某個故障中的外部依賴,降低系統負載或止血
  • Permission Toggle(權限開關):依角色或訂閱方案決定功能是否可見,本質上是長期存在的權限控制,不是臨時性的釋出開關

適合的情境:

  • 想要把「部署」的風險跟「對使用者開放功能」的風險分開處理,兩者用不同的節奏推進
  • 功能要不要開放,需要由業務端自主決定時機(例如配合行銷活動時間點),而不是綁死在部署排程上
  • 需要對特定使用者群組(VIP、內部員工、特定地區)先行開放做驗證

使用風險:

  • 開關地獄(Flag Hell):Release Toggle 如果沒有在功能穩定後清理掉,程式碼裡會累積大量 if (flag) 分支,多個開關交叉組合時,程式碼的實際執行路徑數量會指數增長,變得極難測試、極難理解
  • 測試矩陣爆炸:QA 理論上要覆蓋每個開關「開/關」兩種狀態的組合,開關一多,完整測試所有組合在實務上幾乎不可能,通常只能挑重點組合驗證
  • 開關依賴本身是新的故障點:如果開關狀態是從遠端的 Feature Flag 服務即時查詢,那個服務本身的可用性、延遲,都會直接影響應用程式;務必設計好查詢失敗時的預設值(Fail Open 或 Fail Closed 要依功能性質決定),不然開關系統本身變成單點故障
  • 同樣有相容性問題:如果開關控制的功能牽涉資料格式(例如新邏輯寫入新欄位),開關關閉時期寫入的舊格式資料,開啟後的新邏輯要能正確處理,這跟藍綠、金絲雀面對的是同一類問題,只是換了個地方發生

三者可以疊加使用,不是互斥的選擇

這三個機制作用的層次不同,實務上經常疊加使用:先用金絲雀部署讓新版本的程式碼只接收一小部分流量、驗證程式本身沒有崩潰或效能問題;與此同時,程式碼裡新功能的 Feature Toggle 仍然保持關閉,等到金絲雀擴大到 100%、確認新版本本身穩定之後,才透過 Feature Toggle 真正對使用者開放這個功能。「部署」跟「發布」在這個流程裡被完全拆開成兩個獨立的決策點。

機制切換的對象粒度回滾速度
藍綠部署整套執行環境環境層級(全有或全無)快(路由切回),但影響面是全量
金絲雀部署流量比例流量層級(可微調百分比)快,且只影響金絲雀那一部分流量
Feature Toggle程式邏輯分支功能層級(可依使用者群組)最快(改設定,不必重新部署)

共同的核心風險:向下相容

三個機制都建立在同一個前提上:新舊版本(或新舊資料格式)必須在同一段時間內同時存在、同時被使用。藍綠部署的重疊時間最短(切換前後那一刻),金絲雀部署的重疊時間較長(整個逐步放量的過程),Feature Toggle 的重疊時間可能最長(開關關閉的整段期間),但本質上都要面對同一個問題:向下相容(Backward Compatibility)。

資料庫層面常見的做法是「擴張—收縮模式」(Expand-Contract Pattern):

  1. 擴張:新增欄位或新增表格,但不刪除、不修改舊有結構,讓舊版本完全不受影響地繼續運作
  2. 雙寫過渡:新版本上線期間,視情況同時寫入新舊兩種格式,確保無論流量落在新版本或舊版本,資料都是完整、一致的
  3. 收縮:等所有流量都已經切到新版本、確認沒有回滾的需求之後,才移除舊欄位或舊表格

API 層面的原則相同:新版本的 API 要嘛保持跟舊版本相容,要嘛做好版本控制(同時提供 /v1、/v2),不能讓還沒升級完的呼叫方,因為後端搶先升級就直接壞掉。

一句話總結

藍綠部署換的是整套環境、金絲雀部署換的是流量比例、Feature Toggle 換的是程式邏輯分支,三者可以疊加使用、各自處理不同粒度的上線風險;但不管用哪一種,只要新舊版本會同時存在,向下相容就是繞不過去的前提,資料庫與 API 的變更都該用「先擴張、再收縮」的方式,讓舊版本在切換的過程中不會被突然打壞。