不可變伺服器
2013 年 6 月 13 日
自動化組態工具(例如 CFEngine、Puppet 或 Chef)讓您可以指定伺服器應如何組態,並使新舊機器符合規範。這有助於避免脆弱的 雪花伺服器 問題。此類工具可以建立 鳳凰伺服器,可隨意中斷並重建。不可變伺服器是此方法的合乎邏輯的結論,一旦部署伺服器,就永遠不會修改,僅用新的更新實例取代。
自動化組態工具通常與 組態同步 搭配使用,您讓伺服器執行一段潛在很長的時間,重複套用組態以使其符合最新的規範。理論上,伺服器可以無限期執行,並且它們將保持完全一致且最新。實際上,不可能完全管理伺服器的組態,因此組態漂移的範圍很大,而且執行中的伺服器會發生意外變更。
這正是 鳳凰伺服器 有幫助的地方。

透過從基本映像頻繁銷毀並重建伺服器,伺服器 100% 的元素都會重設為已知狀態,而無需花費大量時間來指定和維護詳細的組態規範。
一旦您開始使用鳳凰,組態管理的重點就會轉移到基本映像的管理。修正、變更和更新會套用到基本映像,而不是執行中的系統。每次您想要新的更新時,您會修改基本實例,並透過自動化測試框架執行它。只有當它們通過這些步驟時,您才會建立新的伺服器。
所以,phoenix 伺服器的完整狀態是由基本映像 + 自動化配置管理 + 資料 [1] 組合而成的,這降低了自動化配置管理伺服器 100% 的壓力。
但儘管我們可以在伺服器短暫的生命週期中持續執行配置管理更新,但這樣做價值較低。事實上,不這樣做有相當大的價值,因為對正在執行的系統進行任何變更都會帶來風險。
這自然會導致不可變伺服器 [2]。

一旦您從經過良好測試的基本映像中啟動伺服器執行個體,就不應該執行配置管理工具,因為它們會為執行個體建立未經測試的變更機會。任何需要的變更都可以對基本映像進行變更、測試,然後再推出。沒有變更的伺服器會被終止並替換。
如果這聽起來很熟悉,那是因為它遵循 持續整合 和 持續傳遞 的做法。使用軟體的持續傳遞,將應用程式的特定版本編譯成可部署的成品僅一次會更安全,並知道您在所有環境中部署和執行一致建置的應用程式。使用不可變伺服器,您可以對基本映像進行每次變更,然後您知道從該映像建立的所有執行個體都是一致的。
伺服器角色執行個體之間的主要差異來自於組態設定,這些設定應該來自伺服器外部。例如,大多數虛擬化和雲端平台提供一種方式,在提供新執行個體時設定元資料值,然後正在執行的伺服器可以讀取該值。新的伺服器也可以從集中式註冊表中提取組態值,例如 Zookeeper。
建議將不可變伺服器的每個執行個體組態項目的數量和範圍減到最少,並在可行的情況下透過自動化測試執行這些變更。
處理資料
如果伺服器是可拋棄的,那麼它們上的資料通常不是。在實作 phoenix 或不可變伺服器時,您應該考慮在伺服器被毀壞和建立時需要保留哪些資料,以及為了透過新增額外的伺服器來擴充,哪些資料必須複製。
當資料有價值但不需要在執行階段時,您可以將資料從執行個體中傳送出去,例如將日誌檔傳送至集中式 syslog 伺服器。像 NFS 這樣的共享檔案系統可以讓伺服器使用檔案,或許是存在於 SAN 上。雲端平台通常提供可安裝的儲存裝置,例如 AWS EBS 卷,當舊的執行個體被毀壞時,可以將其附加到新的伺服器執行個體,或在擴充叢集時快速複製並附加到複製品。通常,您可以將責任推給其他人維護的服務,例如 Amazon 的 RDS 資料庫服務。
進一步閱讀
Netflix 一直處於使用不可變伺服器模式的最前線,儘管我不知道他們是否使用過這個術語。他們開源了 Aminator 工具,他們開發這個工具來管理 AMI 執行個體,以便在 Amazon 的 AWS 雲端上使用,並 部落格記錄了他們如何隨著經驗使用這個模式。有趣的是,實例化新執行個體的速度一直是他們的關鍵驅動力,因為這有助於他們自動擴充和復原。
備註
1: 資料涵蓋許多事項,包括資料庫檔案和其他應用程式管理的資料、執行階段狀態、其他執行階段產生的資料(例如記錄檔)和外部提供的組態。
2: 我的同事 Ben Butler-Cole 在 Thoughtworks 內部郵件清單上,為此模式創造了「不可變伺服器」一詞。