🎯 什麼情境該想到我
當你「想把新版部署上生產、但又不敢讓客戶當白老鼠,而且出事時要能立刻退回去」的時候。
⚙️ 怎麼用(步驟 / 公式)
意圖:用兩套生產環境輪流當「上線中」與「待命中」,讓部署跟切流量變成兩個獨立動作,隨時可退。
做法要點:
- 準備 兩套生產環境:blue 與 green,任何時刻只有其中一套在承接客戶流量(書中圖 20 是 green 在服役)。
- 把新版部署到非活躍的那一套,在不干擾使用者體驗的情況下做測試。
- 確認一切運作正常後,把流量導到 blue,於是 blue 變 live、green 變 staging,角色互換。
- Roll back 就是把客戶流量導回 green——不需要反向部署,只是把流量切回去。
- 切換動作本身可以非常簡單:改一個 router 設定、改一個 symlink,所以可以在正常上班時間部署、離峰時間切換。
- 這個模式最簡單,也極容易加裝到既有系統上(retrofit)。
處理資料庫變更(兩個版本共用同一個資料庫時會卡住,因為 schema 變更/增刪改表格欄位無法同時支援新舊兩版):
- 解法 (a):建兩個資料庫(blue DB 與 green DB)。發布時把 blue 資料庫設為唯讀 → 備份 → 還原到 green 資料庫 → 再把流量切到 green。
- 缺點:若之後要 roll back 回 blue 版,除非先手動把交易從 green 遷移回來,否則可能遺失交易。
- 解法 (b)(書中偏好):把資料庫變更與應用變更解耦,做兩件事:
- 只對資料庫做加法變更(additive changes),絕不變動(mutate)既有的資料庫物件;
- 應用程式不對「生產環境會是哪個資料庫版本」做任何假設。
- 書中明說這跟傳統訓練我們「避免資料重複」的思維非常不同。
案例:
- IMVU(約 2009):採用「資料庫變更與應用變更解耦」的做法,讓他們能每天做 50 次部署,其中有些部署包含資料庫變更。
- Dixons Retail POS(2008):Dan North 與 Dave Farley 把藍綠部署用在數百家門市、數千台 POS 終端的厚客戶端升級上。傳統做法是 POS 客戶端與中央伺服器一次大爆炸同時升級,需要大量停機(常常整個週末)與大量網路頻寬。因為網路頻寬不足以同時升級所有 POS,他們改為建立兩個版本的中央伺服器同時支援新舊 POS 客戶端,並在計畫升級的數週前就開始透過慢速網路把新版客戶端安裝檔送到門市、以「非啟用(inactive)狀態」佈署下去,舊版照常運行。等到全部備妥後,由各店店長自行決定何時啟用新版——有些立刻用、有些選擇等待。結果是更平順更快的發布、店長滿意度更高、對門市營運的干擾大幅降低。
原文:「and green becomes staging. Roll back is performed by sending customer traffic」(L6551,接 L6552「back to the green environment.」)
原文:「additive changes to our database, we never mutate existing database objects,」(L6580)
原文:「enabling them to do fifty deployments per day, some of which required」(L6586,接 L6587「database changes.」)
🧪 我實際套用的紀錄
- (待填)
⚠️ 注意 / 什麼時候不適用
- 兩套環境共用一個資料庫時一定會出問題,必須先選定上面兩種解法之一,否則藍綠部署等於沒做。
- 選解法 (a) 就要接受「roll back 可能掉交易」的風險,或準備好手動遷移流程。
- 解法 (b) 要求開發端配合(只做加法變更、程式不假設 DB 版本),是架構與紀律問題,不是純基礎設施問題。
- 需要維持兩套生產環境的成本;此模式屬於 environment-based release pattern,通常不需改動應用程式碼,但也因此無法做到「單一功能」等級的細緻控制——那要靠 功能開關。