[軟體概念入門系列] 自動化部署與Config

Brett Yu
Brett’s dev log
Published in
6 min readNov 4, 2023

本節說明應用程式的自動化部屬, Config相關概念以及部署策略

Continuous Delivery與Continuous Deployment

Continuous delivery是對於每一個程式碼的Commit, 都可以完成相關的自動化測試, 並自動生成對應的Package放到等待部署的位置, 等待上版人員手動觸發後即可進行上版到Production, 要達到這樣的目標, 必須要先完成前置的Continuous Integration作業

Continuous Deployment則是連部署的作業都不需要有人員介入, 只要滿足對應的條件(如所有End to end測試都通過)即會自動上版至Production

Ansible與Ansible Tower

Ansible是一個開源的組態管理工具, 可以將需要執行的指令推送到目標伺服器上執行, 並可以預先定義好Playbook進行一系列的命令操作, 並依據動作的執行結果可以有不同的後續處理

如我們要對10台新伺服器做同樣的安裝Java runtime及Kafka, 並在Kafka安裝完成後新增一個設定檔到系統目錄中, 此時可以撰寫Ansible playbook來定義這些步驟, 並可定義若第一個步驟失敗, 則後續的步驟都取消執行等條件判斷

Ansible也提供許多包裝過的內建指令, 開發者可以直接使用而不用直接對Server執行CLI, 當然要直接使用CLI也是支援的

以下是一個實際的Ansible playbook範例, 涵蓋兩個步驟分別是更新資料庫到最新版, 並確保服務是啟動中, 這樣的檔案格式稱作為YAML檔

---
- name: Update db servers
hosts: databases
remote_user: root

tasks:
- name: Ensure postgresql is at the latest version
ansible.builtin.yum:
name: postgresql
state: latest

- name: Ensure that postgresql is started
ansible.builtin.service:
name: postgresql
state: started

Ansible Tower則是一個協助使用者可以執行及管理Ansible各種playbook及參數的平台, 並有權限管理及Log等功能

Config

在系統中常會有一些數值或行為會因為不同環境而有不同的設定, 比如在Local, DEV, QAT環境不實際發送OTP, 而STG, PROD則需要正常發送OTP, 或是同一個Domain在測試環境可以註冊多個幣別的Player, 而在PROD僅層註冊對應的幣別Player

由於這些數值或開關會依據環境而改變, 故不適合將值直接明確寫在程式中, 因為若這些值需要修改, 則程式就會需要重新編譯產生出新的版本並進行上版才能生效, 因此一般來說公司內的作法會將這些值放在以下幾種Config中

  • 程式會讀取的Config File

最常見的做法, 會透過部署時將不同環境需要的值寫入 手動調整後可能會需要重新啟動程式

  • 資料庫的資料表

開發人員認為這個值之後有可能開放給使用者自行設定 依據程式寫法不同, 調整後仍有可能會需要重新啟動程式

  • Consul Key Value

通常為OpenResty(Nginx)使用

  • Container的環境變數

為部署時設定, 大部分是用來寫入程式會讀取的Config File, 但也有部分程式會直接讀取

CD流程

下圖是CD流程部署到QAT及IDC STG, Prod的流程簡述圖

向下相容與破壞性改動

當一個應用程式或Library/Framework的改動, 可以讓對其依賴的Client端不需要一起更新也可維持正常運作, 則代表此版本有向下相容, 反之則稱為破壞性改動 (Breaking Change)

一般來說對程式的Contract, 亦即Input, Output的欄位名稱有變更或刪除, 而程式邏輯的調整也可能會造成破壞性改動, 這些都是屬於開發人員依據當次改動需要做的分析與規劃

為避免發生破壞性改動, 通常會保留舊的Interface或邏輯, 並將新的邏輯放在新的method或api url中, 直到確定舊的邏輯再也沒有任何Client使用, 才移除舊版程式

部署策略

Recreate 重建部署

將舊版本停止後, 再啟用新版本並將流量導到新版本

Pros: 單純, 確保所有流量都是同時導到新版

Cons: 舊服務停止時間及新服啟動時間就是服務中斷時間

Ramped (Rolling) 滾動部署

逐一取代舊版本的Instance

Pros: 不影響服務運行

Cons: 花費較久時間, 流量較難以控制會導向哪一個版本需做好向下相容

Blue/Green 藍綠部署

完成所有新版本Instance的部署後, 再一次切換流量, 完成後才刪除舊版本Instance

Pros: 不影響服務運行, 可精確控制流量導轉

Cons: 需要使用雙倍系統資源

Canary 金絲雀部署, 灰度部署

僅部署部分新版Instance並將少部分流量導轉至新版以觀察新版程式是否正常, 之後才完整切換到新版

Pros: 不影響服務運行, 在影響少部分使用者的情況下實際觀察是否發生問題, 可快速Rollback

Cons: 需要更長的部署時間

A/B Testing A/B部署

在特定條件(瀏覽器種類, 地理位置或任何商業考量的其他條件)下, 將部分使用者導向新版, 並觀察使用者行為, 通常用在畫面調整, UX流程優化等需要觀察實際使用者體驗的情況

Shadow 影子部署

雙版本並行, 所有進到舊版本的流量也都複製一份到新版本, 藉此進行新版本是否符合功能, 效能等要求

Pros: 用實際Production流量來進行測試

Cons: 需要兩倍以上成本, 資料庫等共用資源也須拆分, 且需要考慮是否對外部系統產生重複交易

--

--