升級的共通操作框架
環境與系統升級的核心約束是系統在升級過程中要持續服務客戶。這個約束排除了「關機 → 換版本 → 開機」的簡單路徑,取而代之的操作模式是四個階段:評估新舊版本的差異、在旁邊建一個新環境驗證、把流量分批切過去、確認沒問題後退役舊環境。這四個階段不管升級的對象是 runtime 版本、資料庫引擎、作業系統還是整個平台,框架相同,差異落在每個階段的具體操作與風險點。
Phase 1:差異評估
差異評估的產出是一份 change manifest——列出所有已知的新舊差異、每項的風險等級、以及需要的應對措施。這份清單是後續所有階段的依據:平行環境要驗證清單上的每一項、切換策略要先處理高風險項、退役前要確認清單上的所有相容性問題都已解決。
差異的三個維度
第一個維度是目標本身的變化。版本升級要看 changelog、breaking changes list、deprecated features list。平台遷移要看兩個平台的功能差異(共享主機沒有的 cron 彈性、VPS 有的 SSH 存取)。資料庫升級要看 SQL 語法差異、預設行為變更(如 MySQL 8.0 的 caching_sha2_password 預設認證方式)。
第二個維度是依賴關係。升級 PHP 版本時,所有 Composer 套件都可能受影響;升級 MySQL 時,ORM 的 SQL 生成可能不相容;遷移平台時,原本靠主機面板設定的 cron job 要改用系統 crontab 或雲端排程。依賴關係沒列完整,平行環境的測試就會漏掉受影響的元件。
第三個維度是過渡期的雙版本相容性。升級不是瞬間完成的——在切換的過程中,系統的某些部分跑新版本、某些部分跑舊版本。這段期間兩個版本必須能共存:資料庫的 schema 要同時相容新舊版本的程式碼、API 的回應格式要讓新舊版本的客戶端都能處理、session 格式要能跨版本延續。
風險分級
| 風險等級 | 定義 | 應對方式 | 範例 |
|---|---|---|---|
| 低 | 向後相容、不需改 code | 平行環境驗證即可 | PHP 8.x 的效能改善 |
| 中 | 需要改 code 但改動明確 | 先改 code、確認新舊版本都能跑 | deprecated function 替換 |
| 高 | 行為變更、可能影響商業邏輯 | 需要完整的功能測試 + 人工驗證 | 浮點數精度變更、排序預設值變更 |
| 阻塞 | 無法在新版本運作、沒有替代方案 | 必須在升級前解決或決定放棄升級 | 依賴的套件不支援新版本 |
每一項差異分級後,高風險和阻塞項決定升級的可行性與時程。阻塞項超過團隊能處理的量時,升級可能需要拆成多個階段(先升到中間版本、再升到目標版本)或延後。
時程與管理層報告
差異評估的時程通常佔整個升級的 20-30%——看起來「還沒開始做」但這段時間的產出(change manifest)決定了後面所有階段的範圍。向管理層報告時用 change manifest 的風險分級表:「共 N 項差異,其中 X 項低風險、Y 項中風險、Z 項高風險、W 項阻塞。中高風險項的處理估計 M 天,阻塞項的替代方案評估需要額外 K 天。」
Phase 2:平行環境驗證
平行環境驗證的責任是用事實證明「新版本在跟 production 相同的條件下能正常運作」。它的產出是一份驗證報告——每一項 change manifest 上的差異都標上「已驗證通過 / 有問題待修 / 不影響」。沒有這份報告就切換,等於在賭新版本會正常。
建立平行環境
平行環境跟 production 越相似,驗證結果越可信。理想狀態是完全複製 production 的架構(同規格、同設定、同網路拓撲),只差目標元件的版本不同。成本限制下的折衷是用縮小版(較小的 instance、較少的資料量),但關鍵設定(PHP 模組、MySQL 參數、安全設定)必須跟 production 一致。
資料的處理要特別注意。用 production 的資料副本驗證最可靠(能觸發真實的邊界狀況),但如果資料含 PII,需要先脫敏處理。另一個選項是用 staging 環境的資料,但要確認 staging 的 schema 跟 production 一致——schema drift 會讓驗證結果失真。
驗證清單
| 驗證項目 | 方法 | 通過標準 |
|---|---|---|
| 應用程式啟動 | 部署到新環境、觀察 log | 無 fatal error、所有服務啟動成功 |
| 自動化測試 | 跑完整測試套件 | 通過率跟舊環境一致 |
| 關鍵業務流程 | 人工操作核心流程(登入、下單、金流) | 每個步驟的結果正確 |
| 效能比對 | 同樣的 workload 打新舊環境 | 回應時間差異 < 10%(或可解釋) |
| 相容性問題 | 逐一驗證 change manifest 的中高風險項 | 每項有「通過」或「已修」的紀錄 |
| 外部整合 | 第三方 API callback、webhook、email | 外部服務能正常與新環境互動 |
平行期的時間長度
平行環境跑多久才能切換?取決於業務週期。如果系統有月結、季結的批次處理,平行環境至少要跑過一次完整週期。電商系統要跑過至少一個促銷活動。沒有明顯週期的系統,一到兩週的平行驗證通常足夠發現主要問題。
Phase 3:分批切換
分批切換的核心原則是不一次切 100%——先把最低風險的流量導到新環境,觀察一段時間確認正常,再逐步增加比例。
切換策略
| 策略 | 適用環境 | 操作方式 | 回退速度 |
|---|---|---|---|
| DNS 權重切換 | 有多組 server 的環境 | Route 53 weighted routing 或類似機制,逐步調整新舊比例 | 分鐘級(改 DNS 權重) |
| Blue-green | 有 load balancer 的環境 | 新舊環境各掛在不同 target group,LB 切換指向 | 秒級(切 target group) |
| Canary | 容器化或 serverless 環境 | 新版本只接 5% → 20% → 50% → 100% 流量 | 秒級(調整 weight) |
| 維護窗口 | 共享主機(無 LB) | 公告停機時間、切換、驗證、恢復服務 | 分鐘級(FTP 上傳舊版) |
共享主機通常只能用維護窗口策略——沒有 load balancer 做流量分配、沒有 DNS 權重可調。維護窗口的關鍵是時間規劃:備份(15 分鐘)→ 切換(30 分鐘)→ 驗證(30 分鐘)→ 恢復或回退(15 分鐘),在窗口內必須完成全部步驟,超時就回退。
切換期間的監控
切換開始後要密切觀察的指標:
- 錯誤率:5xx / 4xx 比例相對於切換前的基線
- 回應時間:p50 和 p99 相對於基線
- 業務指標:轉換率、訂單數、付款成功率(如果適用)
- 外部整合:第三方 callback 是否正常
回退觸發條件
在切換前就定義好回退條件,避免事故發生時還要開會決定要不要退:
- 錯誤率超過基線的 2 倍持續 5 分鐘 → 回退
- 核心業務流程失敗(登入、結帳、金流) → 立刻回退
- 回應時間超過基線的 3 倍持續 10 分鐘 → 回退
回退不是失敗——它是風險控制機制的正常運作。回退後排查問題、修正、重新走 Phase 2 驗證、再嘗試切換。
切換的通知
| 對象 | 通知時機 | 內容 |
|---|---|---|
| 內部團隊 | 切換前 24 小時 + 切換開始時 | 切換時間、影響範圍、回退計畫 |
| 客戶(如有 SLA) | 切換前 1 週 | 預計維護窗口、預期影響 |
| 外部 vendor | 切換前 1 週 | endpoint 變更(如有)、IP 變更(如有) |
Phase 4:退役舊環境
切換完成後不要立刻刪掉舊環境——保留 1-2 週的冷備。這段時間處理長尾問題:DNS 快取還沒更新的客戶端、排程任務還指向舊 endpoint 的外部系統、舊環境上可能還有未遷移的資料。
退役前的檢查
- 舊環境的存取 log 是否歸零?(有流量代表還有東西指向它)
- 所有 cron job 是否都已在新環境運行?
- 外部系統的 webhook / callback URL 是否都已更新?
- 舊環境上有沒有需要歸檔的資料?(log、上傳檔案、備份快照)
退役步驟
- 停止舊環境的應用服務(但不刪除)
- 觀察 1 週——如果有問題可以快速重啟
- 匯出需要保留的資料(log、uploaded files)
- 刪除舊環境的運算資源(VM、容器)
- 保留舊環境的最後一份備份 30 天,作為最後的保險
- 清理舊環境的 DNS 記錄、SSL 憑證、IAM 角色
貫穿全程的升級紀律
一次只升一個東西
同時升級 PHP 版本 + 遷移到新主機 + 重構資料庫 schema,出問題時無法判斷是哪個變更造成的。每次升級只改一個主要元件,穩定後再升下一個。如果業務壓力要求一次完成,至少在 Phase 2 的驗證環境裡逐一引入、逐一確認。
每個階段轉換前備份
Phase 1 結束前備份 production 現況、Phase 3 切換前備份、Phase 4 退役前備份。三份備份各自獨立、各自有還原驗證。備份不只是「做了」——要實際測試過還原,確認備份的完整性。
記錄每一步
每個升級操作記錄在 repo 的 changelog 裡:什麼時間、誰做的、改了什麼、觀察到什麼結果。升級出問題時,changelog 是回溯「上一步做了什麼」的唯一依據。
在平行階段就練習回退
不要等到 Phase 3 切換時才第一次嘗試回退。在 Phase 2 的平行環境裡,刻意從新版本切回舊版本一次,確認回退路徑能走通、回退後服務能正常恢復。回退的演練跟升級的驗證同等重要。
跨分類引用
- → 接手維運:接手後穩定維運的下一步常是升級
- → 模組五:核心服務上 IaC:stateful 資源(RDS、S3)的升級涉及特殊的備份與切換策略
- → 模組八:治理好習慣:升級期間的變更紀錄對齊治理紀律
- → 模組七:infra 走 PR 流程:升級涉及的 IaC 變更走 PR review