# 第十章 - 應用程式的部署跟發布 p.251 ~ 266 本章的重點整理 * 從一開始就使用同一套部署流程,避免過多的特例,造成維護跟管理的困擾,也減少出錯的機會,且讓這套流程成為唯一部署的途徑 * 不只是部署,還原也很重要,所以書裡面推薦了兩個 zero downtime 的部署方法,藍綠部署跟金絲雀 * 透明化的部署資訊,包括個環境中目前使用的版本、誰授權部署、是誰做了哪些修改等等... ## 建立發佈策略 專案一開始,就要擬定發布的策略,要找來相關的人一起討論出一個策略方向,大家跟著這個方向前進,過程中可能會修修改改,但重要的事所有修正都要有文件做紀錄 這個 policy 需要考慮的東西有以下列的這些 * 誰來做部署跟發布 * 建立一個管理策略 configuration、data * pipeline implement plan * 列舉出 pipeline 整個環境及建置步驟的流程 * deploy 到測試環境及正式環境的流程可能有些許不一樣 * monitoring service 需求 * logging * rollback plan * capacity 預估 * rotate policy 資料或是 log 保存期限 * how to fix & migrate 這些只是盡可能的考慮進去,執行過程中會有許多的變化。 > 「唯一不變的事就是需求一直在變」 ### 發布計畫 不管是用文件、腳本、或是步驟流程來紀錄發布流程,都需要保證這個流程是具有可靠性及可重複性的。 那這個流程內容需要有: * 第一次部署所需的 rundown * 怎麼做冒煙測試 * 出現異常該怎麼撤銷、或是重新部署的步驟 * logging & monitoring * 哪些是必要的資料,該怎麼遷移,需要被紀錄 * backup & restore 機制 這裡特別強調備份及還原的重要性,再引用一下前輩說過的話 > 「重點不是怎樣備份,而是要想怎麼樣去還原」 ### 發布產品 這裡提到比較多跟商業的考量,我想要提一下關於 license 的部分,曾經聽過一個前輩提醒說,要小心 GPL license, 基於 GPL license 有感染性的特性,有參考到 GPL 的軟體要懷著感恩的心,將你的軟體也開源 所以假設再開發的時後有用到 GPL license 的套件,你的軟體也適用 GPL,這個前輩是個個人開發者,開發的東西被敵對大公司眼紅盯上,就抓到 GPL 著個特性,就威脅你要把軟體開源,這樣一來你開發賣錢的東西就不值錢了。 所以提醒大家,在發布產品這個階段也可以把 license 問題考慮進去 ### 應用程式的部署和晉級 如果要讓部署具有一定的可靠性及一致性,最好是每次部署都使用同樣的方法 #### 首次部署 這裡提到首次部署的重要性,我能想到在首次部署就使用實作出來的部署方法作部署的好處: * 還沒上線,不影響服務 * 最乾淨的情況下部署,最能知道我們少了什麼東西 > 因為像是環境建置比較屬於一次性的,建置完成沒多久就忘了,最好的方式還是用腳本或文件做紀錄 所以我們需要盡量在首次部署的時候就使用同一套部署方法 在首次部署後我們可以得到的: * 部署流水線 * staging * CI 流程後的 binary 部署在 staging 上 * 以冒煙測試來驗證 這裡探討到 staging 到底要多像 production 環境? A: 就依 production 環境為主 * 如果是群集的環境,就建個小群集; * 如果是分散節點,就把各節點獨立做一套 至少作業系統、package 要一致,不要裝 IDE ## 對發布流程進行建模並讓建置晉級 前面提到的發布策略、計畫,到自動化部屬,那應用程式越來越複雜,這整個 pipeline 也需要更嚴謹的對待,需要再多考慮一些像是 * 建制需要通過哪些測試階段(整合測試、QA、user test、staging) * 每階段需要達到哪些門檻 * 由誰判斷、批准門檻達標可以進到下個階段 ![](https://i.imgur.com/jLFcGA7.jpg) 另外 pipeline 中還需要可以看到**哪些版本通過階段測試**,並且提供按鈕可以讓該審核人員可以透過 **點擊** 來將建置進入下個階段測試或是部署 讓自動化來部署、測試,讓不是技術人員也可以輕易操作,跟看到目前的狀態 ### 設置的晉級 這裡指的是 configuration,主要部署的不只是 binary,可能有時候設定檔也需要更新,所以最好的做法是用簡單的冒煙測試,也把設定檔做個驗證 然後再把所有元件 **一起** 晉級到下個階段,盡量避免分開來晉級,以免發生一些不可預期的錯誤,像是資料庫腦裂啊等等的錯誤 ### 編配 假設服務越來越多,有些服務的相依性太複雜,或是共用同樣環境,可以考慮用虛擬化或是 dockerize 的方式來解耦合 ### 部署到試運行環境 最後當然是部署到跟正試環境非常接近的環境試跑,做最後的整合測試,如果公司的 $$ 夠的話,最好是複製一組正式環境,可以順便做容量效能的測試 ## 還原部署與零停機發布 萬一部署失敗是很嚴重的事,所以怎麼還原也是很重要的,下面講到兩種 zero-downtime 的方法,**藍綠部署**、**金絲雀部署** 所以在做發布動作之前,先確保目前狀態的備份及還原的可行性,還是套一句前輩的話 > 「重點不是怎樣備份,而是要想怎麼樣去還原」 ### 透過重新部署還原至原有的正常版本 當然最簡單還原的方法就是,把前一個OK的版本在部署一次,但這樣的話部署過程就會有 downtime,以及較難除錯 所以才需要下面提到的 zero-downtime 的部署方法 ### 零停機發布 就是在正常服務的情況下,瞬間無異常的轉移到新版本,另一方面假設進版有任何錯誤,也要能瞬間轉回原來版本上 ### 藍綠部署 準備兩套一模一樣的環境,將新版部署到另一個環境中,再將線上流量切換過來 ![](https://i.imgur.com/mJ6sKgL.jpg) 另外還有 shadow environment releasing 就是流量切過去另一組之後,退下來的那一組就拿來當測試環境 ### 金絲雀部署 儘管測試再怎麼多,總還是會有 loss 的地方,這時就蠻適合用金絲雀部署方式來測試 就是把新版本部署到少部分的機器上,並在這邊收集新版本的問題,好處是 * 不影響大部分的人 * 很容易還原 * 可以收集使用率、產生收入等等的指標,萬一不好隨時可以收掉 * 只需要少比例的使用者,可以做新版本的容量、效能側試,透過調整使用者的比例來測量機器的 capacity 最後還是建議線上環境中,盡量不要太多不同的版本,以免增加管理上的負擔,也可能會出現一些不可預期的錯誤