你應該直接部署到正式環境 (Prod)

@colemurray
英語2026年8月06日
137K
760
38
34
1.3K

TL;DR

前 Amazon 工程師 Cole Murray 指出,持續部署比排程發布更安全。他概述了一份包含 CI/CD、可觀測性 (observability) 與功能旗標 (feature flags) 的路線圖,以將不可避免的停機影響降至最低。

cole murray - inline image

每次變更都直接部署到正式環境可能很可怕,但不直接部署到正式環境更可怕。

這是當年我在 Amazon 帶領團隊服務數億客戶時所採用的流程。在我的顧問工作中,我帶領多個工程團隊,從每兩週的排程發佈,進化到每次合併(merge)就發佈上線。

先從顯而易見的部分開始:

你一定會造成服務中斷(outage)。這不是「會不會」的問題,而是「什麼時候」的問題。

無論多少單元測試、整合測試、內部試用(dogfooding)、端到端什麼的,或是向部署之神獻祭,都無法抓到所有 bug。

你一週前對功能所做的測試,並沒有涵蓋到你同事最新的變更。

你的測試是針對同事服務的 pre-prod 版本跑的,而那個版本現在已經改變,還包含了一個向後不相容的變更。

你等得越久,release 上堆疊的變更就越多。如果真的需要 rollback,你得回滾兩週的變更,而不是 1-2 小時的變更。

如果我們接受「服務中斷無可避免」這項前提,花費大量資源為 release 做 QA 就顯得意義不大;相反的,我們應該把資源集中在監控與觀察 release,並準備好在服務中斷發生時立即處理。

接下來,我們來談談怎麼達成:

前置條件:

CI/CD

測試的重要性遠低於你的想像。測試無法證明你的變更在正式環境是安全的,沒有任何東西能證明。測試的價值在於讓失敗變得很便宜。在 CI 抓到的 bug 只花幾分鐘;在正式環境抓到的 bug 會燒掉你一整個晚上做 rollback。

所以,每次 merge 都要跑完整的測試套件,或至少作為 pipeline 的一部分:單元測試、整合測試、端到端測試。Bug 在 pipeline 中走得越遠,解決的成本就越高。

監控/可觀測性(Monitoring/Observability)

重點在於盡可能早地抓到 regression。要達成這點,你需要一流的監控。具體形式包括:

  • metrics:錯誤率、延遲、可用性
  • 帶有 correlation id 的 logs
  • 針對上述兩者設定的 sev-3 與 sev-2(paging)alarms

調整 alarm 閾值既是一門藝術,也是一門科學。你需要在敏感度與真實 incident 發生時的反應速度之間取得平衡。sev-2 的目標警示時間應該是 5-10 分鐘。

一開始,你的設定很可能會出錯,而且很可能太敏感。不幸的是,這主要靠試誤來學習,所以你可能會先經歷幾次凌晨 2 點被叫醒。

Feature Flags

任何有風險的變更,都應該透過 feature flag/remote config 來發佈。Feature flag 讓你能在幾分鐘內回滾或關閉任何變更,而不需要回滾整個部署。此外,如果你的 feature flag 服務支援的話(應該要支援),你可以按百分比或特定群組逐步推出功能,進一步降低不良變更的影響。

這讓我們能將「部署程式碼」與「啟動程式碼」兩件事解耦。這雖然細微,卻是降低風險的遊戲規則改變者。

注意:你需要一個清理這些 flag 的流程。理想上,每建立一個 flag 就開一張移除 ticket。否則,當你的 feature flag 服務掛掉時(它總會掛的),你會遭遇嚴重的 regression。想知道我怎麼知道的嗎?問我就好。

自動回滾(部署時的 circuit breaker)

部署時的 circuit breaker 是一種功能:當你在將部署推送到整個 fleet 的過程中,看到特定數量或比例的錯誤時,就能自動回滾部署。現在大部分雲端服務供應商都有這個功能,勾選一個核取方塊即可。

向後相容的變更

你本來就應該這樣做,但每次 commit 都部署會強迫你落實這項做法。在滾動部署(rolling deployment)期間,舊版本和新版本會同時運行。每一項變更都必須能與前一個版本並存。你過去靠「半夜部署」來閃避這個問題的招數,已經行不通了。

部署策略

有了上述基礎,我們可以來看看幾種不同的部署策略,幫助你在推出變更時降低風險。

單一主機(Canary)

單一主機部署是將你的變更部署到整個 fleet 中的一台機器上。這樣可以將任何不良變更的影響範圍縮小到只有一台 host。

你部署後讓它運行一段時間,接收整體流量中的一小部分。你在這台機器上設定好監控與 alerting,一旦有任何問題就會發出警示。

滾動部署(Rolling Deployments)

滾動部署讓你能按百分比逐步推出,如果發生災難性錯誤,你可以在它影響所有機器之前發現,然後開始回滾。

區域 rollout

隨著公司成長,你最終會有多區域部署。與其同時部署到所有區域,你可以先部署到某一個特定區域(通常是流量最低的那個)。

不適用的情況

App Store

發佈手機 App 並不完全適用這個指南。App Store 的審查佇列會限制你的部署節奏,需要不同的策略。

認證環境

醫療設備、航空電子、工業控制等。如果你需要監管機構認證 build,你就無法持續部署。

地端/自架(On-prem / Self-hosted)

你無法控制升級時機。你還是可以對你營運的所有系統持續部署,但必須為每個變更建立版本,由客戶決定何時採用。

從哪裡開始

不要一次做完所有事情。順序很重要:

  1. 讓 CI 保持綠色且快速。理想上 15 分鐘內完成
  2. 針對錯誤率、延遲與可用性建立 metrics 與 alarms。這是整個過程中最重要的一環
  3. 把所有有風險的變更放到 flag 後面
  4. 加入單一主機部署 + 自動回滾
  5. 刪掉 release 行事曆
  6. 既然不用再安排 release,為你多出來的時間找新的用途

我合作過的大多數團隊大約花一季就能完成這些。工具反而是最簡單的部分。組織流程,以及打破「排程發佈很安全」的幻覺,才是最困難的部分。

如果你的團隊還在用 release 行事曆,而且想擺脫它,那就是我在做的工作。私訊我。

一鍵儲存

使用 YouMind AI 深度閱讀爆款文章

保存原文、追問細節、總結觀點,並在一個 AI 工作空間裡把爆款文章沉澱成可複用筆記。

了解 YouMind
寫給創作者

把你的 Markdown 變成乾淨的 𝕏 文章

圖片上傳、表格、程式碼區塊,往 𝕏 上手動重排太痛苦。YouMind 把整篇 Markdown 一鍵轉成乾淨、可直接發佈的 𝕏 文章草稿。

試試 Markdown 轉 𝕏

更多可拆解樣本

近期爆款文章

探索更多爆款文章