🎯 什麼情境該想到我
當你「每次部署都等於一次對客戶的發布,所以只敢挑半夜上線、也不敢提高部署頻率」的時候。
⚙️ 怎麼用(步驟 / 公式)
意圖:把「部署」與「發布」拆成兩個獨立的動作,讓部署可以又快又頻繁地做,而何時把功能開給客戶另外決定。
兩個定義(實務上這兩個詞常被混用,但它們是目的完全不同的兩個動作):
- Deployment(部署)=把特定版本的軟體安裝到某個給定的環境(例如把程式碼部署到整合測試環境,或部署到生產環境)。明確地說:一次部署可能伴隨、也可能不伴隨任何對客戶的功能發布。
- Release(發布)=讓某個功能(或一組功能)對全部客戶、或某個客戶分群可用(例如「讓 5% 的客戶群可以使用該功能」)。
架構要求:
- 程式碼與環境的架構應該設計成「發布功能不需要變更應用程式碼」。
責任劃分:
- 把 deployment 與 release 混為一談,會讓「為成功成果負責」這件事變得困難。
- 解耦後:Dev 與 Ops 負責「快速且頻繁的部署成功」,product owner 負責「發布帶來的業務成果」(即打造並推出這個功能是否值得我們花的時間)。
- 本書前面所有實踐都在確保「開發過程中就不斷快速頻繁地部署到生產」,以降低部署錯誤的風險與衝擊;剩下的風險只有 release risk——放到生產的功能到底有沒有達成想要的客戶與業務成果。
關鍵推論:
- 如果部署前置時間極長,那它就決定了你多久才能對市場發布一次新功能。
- 但當我們能隨選部署(deploy on demand)之後,「多快把新功能開放給客戶」就變成業務與行銷決策,不再是技術決策。
- 副作用:不再需要在半夜或週末做部署來降低影響客戶的風險,可以在一般上班時間部署,讓 Ops 終於能跟其他人一樣有正常工時。
兩大類發布模式:
- Environment-based release patterns(環境型):有兩個以上可部署的環境,但只有一個環境在接收真實客戶流量(例如靠設定負載平衡器)。新程式碼部署到非上線環境,發布動作就是把流量移到該環境。書中說這類模式極其強大,因為通常只需極少、甚至完全不需要變更應用程式。包含 藍綠部署、金絲雀發布、cluster immune system。
- Application-based release patterns(應用型):改造應用程式,讓我們能用小小的組態變更就選擇性地發布與曝光特定功能。例如 feature flags 可以把新功能漸進開放給開發團隊 → 全體內部員工 → 1% 的客戶 → 有信心後才是全體客戶群;這也讓 黑啟動 成為可能——把所有要上線的功能先在生產環境備齊,在正式發布前用生產流量隱形測試數週,好把問題挖出來先修掉。
Continuous Delivery 與 Continuous Deployment 的分野(Jez Humble 於 2015 年為本書更新的定義):
- Humble 說:過去五年這兩個詞造成不少混淆,他自己的想法與定義也和寫《Continuous Delivery》那時不同了;每個組織都該依需求發展自己的變體,我們真正該在意的不是形式而是成果——部署應該是低風險、按鈕式、可隨選執行的事件。
- Continuous Delivery=當所有開發者都以小批量在 trunk 上工作,或都在很快併回 trunk 的短生命週期 feature branch 上工作;且 trunk 永遠保持在可發布狀態;且能在正常上班時間按一個鈕隨選發布。開發者在引入任何回歸錯誤(缺陷、效能、安全、可用性問題)時能得到快速回饋,並立即修掉,讓 trunk 永遠可部署。
- Continuous Deployment=在上述基礎上,定期透過自助方式(由 Dev 或 Ops 部署)把好的 build 部署到生產——典型意義是「每位開發者每天至少部署到生產一次」,甚至自動部署開發者提交的每一個變更。
- 依賴關係:continuous integration 是 continuous delivery 的前提,continuous delivery 是 continuous deployment 的前提。
- 適用範圍差異:continuous deployment 大概只適用於線上交付的 web services;而 continuous delivery 幾乎適用於任何情境——只要你想要高品質、短前置時間、可預測且低風險的部署與發布,包括嵌入式系統、COTS 產品與行動 App。
- 佐證:Amazon 與 Google 多數團隊做的是 continuous delivery,只有部分做 continuous deployment;團隊被授權依自己管理的風險選擇部署方式(Google App Engine 團隊常常每天部署一次,Google Search 則是每週數次)。
原文:「Deployment is the installation of a specified version of software to a given」(L6471,接 L6472–6474)
原文:「becomes a business and marketing decision, not a technical decision. There are」(L6498)
原文:「Continuous deployment is likely applicable in the context of web」(L6897,接 L6898「services that are delivered online. However, continuous delivery is applicable in」)
🧪 我實際套用的紀錄
- (待填)
⚠️ 注意 / 什麼時候不適用
- 解耦本身不會消除 release risk——它只是把部署風險壓下去,讓剩下的風險是「這功能有沒有帶來想要的成果」,那要靠遙測與實驗來處理。
- 環境型模式幾乎不動應用程式碼,但粒度粗;應用型模式粒度細,代價是必須改應用程式、需要 Development 參與。兩類通常要合用。
- 別把 continuous deployment 當成所有團隊的目標:書中明說它大概只適用於線上交付的 web services,嵌入式/COTS/行動 App 該追求的是 continuous delivery。
- 沒有主幹開發與可發布的 trunk,continuous delivery 的定義就不成立,硬做只會得到假的「按鈕式發布」。
🔗 相關工具
- 藍綠部署(環境型發布模式,兩套生產環境切流量)
- 金絲雀發布(環境型,自動逐級晉升+叢集免疫系統)
- 功能開關(應用型,用組態變更選擇性曝光功能)
- 黑啟動(應用型,發布前用生產流量隱形測試)
- 工具-部署管線與持續交付(本條是持續交付的定義基礎與前提)
- 主幹開發(trunk 永遠保持可發布狀態,是 continuous delivery 的定義要件)
- 自動化自助部署(「自助方式部署好的 build 到生產」正是 continuous deployment 的定義)
- A-B測試與假設驅動開發(解耦後剩下的 release risk 靠實驗處理)
- 工具-三步工作法(快速頻繁部署是第一步「流動」的具體展現)
- DevOps手冊