第十章:部署與發布應用程式#
本章探討如何將應用程式部署(Deploy)到各環境,以及如何將其發布(Release)到正式環境。技術上,部署到測試環境與正式環境應使用同一套自動化流程,差異僅在於組態設定檔。本章同時介紹兩個強大的技術——藍綠部署(Blue-Green Deployments)與金絲雀發布(Canary Releasing)——實現零停機時間的發布與回滾。
建立發布策略(Creating a Release Strategy)#
發布策略的核心在於讓所有利害關係人(stakeholders)在專案規劃階段就達成共識,形成對部署與維運的共同理解。
發布策略應涵蓋的要點#
| 要點 | 說明 |
|---|---|
| 各環境的部署負責人與發布負責人 | — |
| 資產與組態管理策略 | Asset and Configuration Management Strategy |
| 部署技術方案 | 須由開發與維運團隊共同決定 |
| 部署管線的實施計畫 | — |
| 可用環境列舉 | 驗收測試、容量測試、整合測試、使用者驗收測試(UAT)等環境,以及建置版本在各環境間的推進流程 |
| 部署流程描述 | 變更請求、審批程序等 |
| 監控需求 | 應用程式應提供的 API 或服務,以向維運團隊回報狀態 |
| 組態管理方式 | 部署時期與執行時期的組態如何管理 |
| 外部系統整合 | 何時測試、如何與供應商溝通 |
| 日誌記錄 | 讓維運人員能判斷應用程式狀態並識別錯誤 |
| 災難復原計畫 | Disaster Recovery Plan |
| 服務等級協議(SLA) | 是否需要容錯移轉(failover)等高可用性策略 |
| 正式環境規模與容量規劃 | 資料量、日誌、頻寬、磁碟空間、延遲等 |
| 歸檔策略 | Archiving Strategy |
| 首次部署到正式環境的方式 | — |
| 缺陷修復與補丁流程 | — |
| 正式環境升級流程 | 包含資料遷移 |
| 應用程式支援方式 | — |
發布計畫(Release Plan)#
首次發布通常風險最高,需要特別規劃。發布計畫除了發布策略的內容外,還應包含:
| 項目 | 說明 |
|---|---|
| 首次部署應用程式的步驟 | — |
| 冒煙測試(Smoke Test) | 部署過程中對應用程式及其依賴服務的驗證方式 |
| 回退步驟 | 部署失敗時的處理流程 |
| 備份與還原 | 應用程式狀態的備份與還原步驟 |
| 升級步驟 | 不破壞狀態的升級流程 |
| 重啟或重新部署 | 應用程式失敗時的處理步驟 |
| 日誌位置與內容說明 | — |
| 監控方法 | — |
| 資料遷移 | 發布過程中所需的資料遷移步驟 |
| 問題日誌 | 歷次部署的問題記錄及其解決方案 |
發布產品(Releasing Products)#
若專案產出為商業產品,還需額外考慮:定價模式、授權策略、第三方技術的版權問題、包裝、行銷素材、產品文件、安裝程式、銷售與支援團隊準備。
部署與推進應用程式(Deploying and Promoting Your Application)#
可靠部署的關鍵是持續練習:對所有環境(包括正式環境)使用同一套流程。
首次部署(The First Deployment)#
首次部署應在第一個迭代中完成。選擇一兩個高優先級但簡單的需求,利用展示(showcase)作為契機,讓應用程式可部署到類正式環境(UAT)。第一個迭代結束時應具備:
| 項目 | 說明 |
|---|---|
| 提交階段(Commit Stage) | 部署管線的第一個階段 |
| 類正式環境 | 供部署使用的環境 |
| 自動化流程 | 從提交階段產出的二進位檔部署到該環境 |
| 冒煙測試 | 驗證部署成功且應用程式正在執行 |
作者認為這是少數應優先考慮技術價值而非業務價值的情境,可視為「啟動開發流程的引水」(priming the pump)。
類正式環境的特徵#
- 執行與正式環境相同的作業系統
- 安裝與正式環境相同的軟體,且不安裝任何開發工具鏈(編譯器、IDE 等)
- 盡可能以與正式環境相同的方式管理
- 對於用戶端安裝軟體,環境應能代表客戶的硬體配置
**虛擬化(Virtualization)與雞群計數法(Chicken-counting: 0, 1, many)**是好幫手。若正式環境有 250 台 Web 伺服器,2 台就足以代表關鍵的行程邊界。
建模發布流程與推進建置版本#
部署管線應模擬你的測試與發布流程。需要釐清:
- 建置版本必須通過哪些階段才能發布(如整合測試、QA 驗收、UAT、預備環境、正式環境)
- 需要哪些審批關卡(Gates)
- 各關卡由誰有權核准

Figure 10.1: An example test and release process diagram
推進(Promotion)是指在部署管線中,按下按鈕將已通過前序階段的建置版本部署到下一個環境。這使部署管線成為一個拉取式系統(Pull System)——分析師、測試人員可自助部署到探索性測試或展示環境,維運人員可按一鍵將任何版本部署到預備或正式環境。
推進組態(Promoting Configuration)#
需要推進的不只是二進位檔,還有環境與應用程式的組態。但並非所有組態都該被推進——例如指向 SIT 資料庫的設定不應推進到正式環境。
應對方式:
- 讓冒煙測試驗證是否指向正確的資源
- 使用 Nagios 等工具監控中介軟體設定
- 撰寫基礎設施測試來檢查關鍵設定
對於 SOA 或元件化的應用程式,所有服務或元件應作為整體一起推進,避免版本不一致導致的問題。
協調(Orchestration)#
當多個應用程式共享環境時需要特別注意:
- 部署新版本時不能影響其他應用程式的運作
- 若應用程式間有依賴(如 SOA 架構),**系統整合測試(SIT)**環境是它們首次彼此溝通的場合
部署到預備環境(Staging Environments)#
在讓使用者接觸應用程式前,應在高度近似正式環境的預備環境中進行最終測試。從專案初期就應開始規劃:
- 確保正式、容量測試、預備環境都已建置完成
- 具備環境組態的自動化流程
- 測量應用程式的暖機時間(Warm-up Period),特別是使用快取的情況
- 測試與外部系統的整合
- 盡可能提前將應用程式部署到正式環境(搭配藍綠部署)
- 考慮先向小群使用者推出(金絲雀發布)
- 每個通過驗收測試的變更都部署到預備環境
回滾部署與零停機發布(Rolling Back Deployments and Zero-Downtime Releases)#
在正式環境除錯幾乎必定導致通宵加班、錯誤操作和不滿的使用者。你需要有辦法恢復服務,再於正常工作時間除錯。
回滾的兩大原則:(1) 發布前備份正式環境的狀態(含資料庫與檔案系統);(2) 在每次發布前演練回滾計畫,包含從備份還原。
flowchart TD
A[需要發布新版本] --> B{允許停機?}
B -->|是| C[重新部署前一版本\n最簡單的回滾方式]
B -->|否| D{有足夠硬體\n支援雙環境?}
D -->|是| E[藍綠部署\n瞬間切換路由]
D -->|否| F{需要漸進式驗證?}
F -->|是| G[金絲雀發布\n逐步擴大流量]
F -->|否| H[滾動更新\n逐台替換伺服器]重新部署前一個良好版本#
最簡單的回滾方式:利用自動化部署流程,從頭重新部署前一個穩定版本(包含重新設定環境)。
優點:
- 固定時間操作,風險較低
- 與已測試過數百次的部署流程相同
缺點:
- 非零停機時間
- 覆蓋新版本後,較難除錯了解問題
- 若還原資料庫備份,會丟失部署後新增的資料
零停機發布(Zero-Downtime Releases)#
零停機發布(又稱熱部署 / Hot Deployment)的核心概念是將使用者從舊版切換到新版的過程近乎瞬間完成,且出錯時也能瞬間切回。
關鍵做法是解耦發布流程的各個部分:在升級應用程式之前,先就位新版本的共享資源(資料庫、服務、靜態資源)。例如,在 URI 中包含版本號,使多個版本同時可用。
藍綠部署(Blue-Green Deployments)#
這是作者所知最強大的發布管理技術之一。核心概念是維護兩套相同的正式環境——藍色與綠色。

Figure 10.2: Blue-green deployments
運作流程:
- 使用者目前被路由到綠色環境(當前正式環境)
- 將新版本部署到藍色環境,並進行暖機與冒煙測試
- 準備就緒後,更改路由器設定將使用者導向藍色環境(切換可在不到一秒內完成)
- 若出問題,只需將路由器切回綠色環境
資料庫處理:
- 若有 schema 變更,無法直接切換資料庫
- 一種做法是在切換前將應用程式設為唯讀模式,複製並遷移資料庫,切換後再恢復讀寫
- 另一種做法是設計應用程式使資料庫遷移可獨立於升級流程執行
成本考量:
- 若預算有限,可在同一環境中執行兩份應用程式副本(使用不同的 port、檔案系統根目錄等)
- 一種變體稱為影子網域發布(Shadow Domain Releasing):用預備環境與正式環境作為藍綠環境,新版部署到預備環境後切換使用者過去,預備環境變成正式環境
金絲雀發布(Canary Releasing)#
金絲雀發布將新版本推出到一部分正式伺服器,以快速取得回饋。如同煤礦中的金絲雀,能迅速發現問題而不影響大多數使用者。

Figure 10.3: Canary releasing
運作流程:
- 將新版本部署到一組無使用者路由的伺服器
- 執行冒煙測試與容量測試
- 開始將選定的使用者路由到新版本(有些公司先選「進階使用者」)
- 確認無問題後逐步增加負載
金絲雀發布的三大好處:
| 好處 | 說明 |
|---|---|
| 容易回滾 | 停止將使用者路由到有問題的版本即可,可從容檢查日誌 |
| A/B 測試 | 將部分使用者導向新版、部分導向舊版,測量新功能的使用率、營收或搜尋結果品質 |
| 容量驗證 | 逐步增加負載,監控回應時間、CPU、I/O、記憶體使用率與日誌中的例外,適合正式環境過大而無法建立等比容量測試環境的情境 |
限制與注意事項:
- 不適用於使用者自行安裝的軟體(除非支援自動更新)
- 對資料庫升級有額外限制:共享資源必須能與所有正式版本相容
- 盡量將正式環境中的版本數量控制在兩個以內
緊急修復(Emergency Fixes)#
無論多緊急,絕對不要繞過你的標準流程。緊急修復必須經過相同的建置、部署、測試、發布流程。直接登入正式環境做未受控的修改會導致:(1) 未經妥善測試的變更可能引入迴歸缺陷;(2) 變更未被記錄,導致環境進入未知狀態。
處理正式環境缺陷的考量:
- 不要在深夜進行,且務必結對操作
- 確保已測試過緊急修復流程
- 使用預備環境驗證緊急修復
- 有時回滾到前一版本比部署修復更好——分析資料遺失、整合與協調問題後再決定
持續部署(Continuous Deployment)#
持續部署將部署管線的最後一步——部署到正式環境——自動化。每次通過所有自動化測試的簽入都直接部署到正式環境。
前提條件#
- 涵蓋整個應用程式的自動化單元測試、元件測試與驗收測試(功能性與非功能性)
- 必須先寫測試,確保需求完成後簽入才能通過驗收測試
持續部署的特性#
- 可與金絲雀發布結合:自動先推出給小群使用者,確認無問題後再全面推出
- 並非適用於所有情境(如合規要求審批、產品公司需支援每個發布版本)
- 更頻繁的發布降低了每次發布的風險,因為每次變更量更小
- 即使無法真正做到持續部署,也應以此為目標建立流程
持續發布用戶端安裝軟體#
對於用戶安裝在自己機器上的軟體,需額外考慮:
| 考量 | 說明 |
|---|---|
| 升級體驗管理 | 最佳做法是背景下載並在下次重啟時靜默升級;若升級失敗,自動回復到前一版本並回報開發團隊 |
| 二進位檔、資料與組態的遷移 | 保留舊版本直到確認升級成功;使用目錄版本化與符號連結 |
| 版本化資料儲存與組態檔 | 每次 schema 或組態變更都建立向前與向後遷移腳本 |
| 測試升級流程 | 在管線中加入專門階段,使用真實資料測試升級 |
| 當機回報(Crash Reporting) | 用戶端軟體需要當機回報框架 |
實用技巧(Tips and Tricks)#
讓負責部署的人參與建立部署流程#
開發人員應從專案開始就主動聯繫維運人員,讓他們參與開發過程。雙方在發布前已多次練習,發布才會順暢。
記錄部署活動#
若部署流程未完全自動化,應記錄所有自動化部署流程複製或建立的檔案,以便除錯。同時維護環境中每台硬體的清單。
不要刪除舊檔案,而是移動它們#
部署時保留前一版本的副本。UNIX 世界的慣例是將每個版本部署到新目錄,用**符號連結(Symbolic Link)**指向當前版本,切換與回滾只需更改連結。
部署是整個團隊的責任#
「建置與部署專家」是一個反模式(Antipattern)。團隊每個成員都應知道如何部署,也應知道如何維護部署腳本。壞掉的部署腳本應讓建置失敗。
伺服器應用程式不應有 GUI#
伺服器應用程式若需要使用者登入並顯示 UI 才能運作,重開機後將停止服務,需人工介入。
為新部署預留暖機時間#
不要在預定時間才啟動網站。在正式上線前,應讓應用程式伺服器與資料庫有足夠時間填充快取、建立連線。可搭配金絲雀發布,讓新伺服器先處理少量請求。
快速失敗(Fail Fast)#
部署腳本應包含測試以確認部署成功。系統初始化時應執行自檢,若遇到錯誤應拒絕啟動。
不要直接修改正式環境#
正式環境應完全鎖定,只有部署管線能對其進行變更(包含環境組態、應用程式與資料)。將授權流程整合到部署管線中,即可獲得完整的稽核軌跡(Audit Trail)——記錄每次變更的內容、時間與核准人。
總結#
部署管線的後期階段處理的是向測試與正式環境部署。這些階段沒有自動化測試,不會通過或失敗,但仍是管線不可或缺的一部分。實作上應能讓任何通過自動化測試的版本,在具備適當憑證的情況下,按一鍵部署到任何環境。
降低發布風險的最佳方式是反覆演練——越頻繁地將應用程式發布到各種測試環境,流程就越可靠。發布策略的規劃應從專案早期就開始,並隨時間演進。最關鍵的是將組織中所有參與交付的角色(建置、基礎設施、維運、開發、測試、DBA、支援)聚集在一起,持續協作以提升交付流程效率。