《微服務設計》閱讀筆記(六)部署
《微服務設計》,Building Microservices,作者Sam Newman,譯者崔力強、張駿,人民郵電出版社,2016年。
筆記中有些內容直接引用原書。
================================================================
第六章 部署
1. 持續集成(CI)。好處:能夠得到關於代碼質量的某種程度的快速反饋;自動生成二進位文件;代碼在版本控制之下,需要的話可以重新生成某個版本的構建物;可以從部署的構建物回溯到對應版本的代碼;有些CI工具可以使運行過的測試可視化。
是否真正理解CI的三個問題:你是否每天簽入代碼到主線?你是否有一組測試來驗證修改?當構建失敗後,團隊是否把修復CI當作第一優先順序的事情來做?
2. 把持續集成映射到微服務
微服務、CI構建、源代碼三者的關係如何?分步驟開始:a. 所有代碼在一個代碼庫、只有一個CI構建,生成多個微服務。缺點:修改某服務的一行代碼,所有服務代碼都需要重新構建和驗證,浪費時間和資源,更會導致不知道哪些構建物要重新部署。b. 還是一個代碼庫,但是多個CI分別映射代碼庫的不同部分。優點:簡化檢出/檢入流程。缺點:會覺得同時提交多個服務修改很簡單,做出將多個服務耦合在一起的修改。c. 每個微服務都有自己的代碼庫和CI,微服務相關的測試應該和其本身的代碼放在一起。優點:修改某個微服務後可以快速驗證,修改代碼只需要做該微服務的構建和測試,代碼庫與團隊的匹配度更高。
3. 構建流水線和持續交付
流水線第一階段運行快速測試,第二階段運行耗時測試。在某個階段失敗,能夠快速反饋,不用進行後面階段的測試,節省時間。越接近後面階段,越能在生產環境下工作。持續交付(CD)檢查每次提交是否達到了部署到生產環境的要求,並持續反饋信息。一個示例流水線的幾個階段:編譯及快速測試、耗時測試、用戶驗收測試、性能測試、生產環境。不要對CI工具擴展來做CD,會導致複雜化,要使用為CD設計的工具。
如果在團隊初始階段,沒有很好識別出服務邊界,可以將所有代碼放在一個庫中,所有服務放在一個構建,減輕跨服務修改所帶來的代價。
4. 平台特定的構建物
各語言有自己的構建物類型和構建工具,Ruby有gem,Java有JAR包或WAR包,Python有egg。對微服務部署來說,還需要一些其它工具。Ruby和Python需要運行在Apache或Nginx中的進程管理器。為了部署和啟動,需要Puppet、Chef和Ansible這樣的自動化配置管理工具,它們支持多種技術棧(編程語言)的構建物。
5. 操作系統構建物
可以使用操作系統支持的構建物來取代不同技術棧的構建物避免部署的複雜性。Redhat或CentOS使用RPM,Ubuntu使用deb包,Windows使用MSI。優點:不用考慮底層技術,使用內置工具即可完成軟體安裝。有些OS包管理器可以完成Chef或Puppet的工作。缺點:剛開始寫構建腳本會比較困難。Linux下的FPM包管理器功能比較完善,Windows的MSI原生打包系統差了不少,NuGet好一些,Chocolatey NuGet提供的功能和Linux上的很接近了。另外,如果多種操作系統部署,代價也就高了。
6. 定製化鏡像
使用自動化配置管理工具,安裝環境仍然耗時耗力。一種方法是創建虛擬機鏡像,其中包含常用的依賴。優點:減少裝環境的時間,缺點:構建鏡像花時間長,鏡像文件大,例如20GB。構建不同鏡像工具鏈不同,AWS AMI、Vagrant鏡像、Rackspace鏡像。Packer可以簡化創建過程,可以支持多種鏡像。
將鏡像作為構建物。不僅將環境部署在鏡像中,將服務也部署進去。
不可變伺服器。部署完成後,如果有人登錄上去對機器做一些修改,可能導致實際配置與源代碼中的配置不一致,導致配置漂移。可以在鏡像創建過程中禁止SSH,確保沒人能登錄修改。
7. 環境。要重視測試環境和生產環境的差異性,要在測試環境儘可能接近生產環境和消耗的人力物力之間做出權衡。
8. 服務配置。服務配置的工作量應該很小,僅僅局限於環境間的不同之處。如果配置修改了服務很多基本行為,或者環境之間配置差異很大,有可能在某個環境中出現特定問題。如何處理不同環境之間的配置差異:a. 每個環境創建一個構建物,配置內建於構建物中。但這樣對於測試環境生成的構建物是無法保證在生產環境能正常運行的。b. 更好的方法是只創建一個構建物,將配置單獨管理。可以用專用系統來提供配置。
9. 服務與主機之間的 映射
一個主機可以運行多少服務?這裡的主機(host)是指運行獨立操作系統的隔離單元。沒有虛擬化的話,一個主機對應的是一台物理機,採用虛擬化的話,對應的就是一個虛擬機。
單主機多服務。優點:管理主機工作量小,硬體成本低,簡化開發人員工作。缺點:監控服務佔用資源困難,服務之間互相影響,單一服務負載過高可能影響其它服務正常運行;服務部署困難,每個服務可能依賴不同的環境;不利於團隊自治,可能需要獨立團隊來管理主機配置,增加協調工作;限制部署構建物的選擇;增加單個服務進行擴展的複雜性,每個服務對於主機的需求未必一致。
應用程序容器。可以利用IIS的.NET應用程序部署或基於servlet容器的Java應用程序部署,將不同的服務放在同一個容器中,再把容器放在單台主機。優點:簡化了管理,對多實例提供集群支持、監控等;節省語言運行時開銷,因為多個服務泡在一個JVM上了。缺點:限制了技術棧的使用;其在內存中共享會話狀態的方式對於微服務來說應該避免,限制了服務伸縮性;容器啟動時間很長;在類似於JVM的平台上,多個應用程序處在一個進程中,分析資源使用和生命周期管理都很困難。建議:對應技術棧的自包含的微服務構建物。如.NET中的Nancy。以及Jetty嵌入式容器中就包含了非常輕量級的HTTP伺服器。這樣能夠保證伸縮性。
每個主機一個服務。優點:避免了單主機多服務的很多問題,簡化了監控和錯誤恢復;減少潛在的單點故障;對某一服務擴展容易;支持不同部署方式如鏡像部署或不可變伺服器。缺點:管理伺服器工作量增加。
平台即服務(PaaS)。PaaS的工作層次比單個主機高,往往依賴於特定技術的構建物,如Java WAR包或Ruby gem等。優點:還能幫助自動配置運行,有的能透明地進行系統伸縮管理。Heroku是一個很好的PaaS平台,能管理服務並以簡單的方式提供資料庫等服務。缺點:出問題時解決起來較困難。越想根據應用程序使用情況來自動收縮,越難以做好。平台盡量滿足的是通用需求,對於應用的特定需求,往往難以滿足。
10. 自動化
軟體部署、服務監控、進程查看和日誌收集等工作在服務規模大的時候,應該靠自動化來解決。理想情況,開發人員使用的工具鏈要和部署生產環境時使用的完全一樣,這樣能及早發現問題。自動化能顯著提高微服務的開發和部署效率。
11. 從物理機到虛擬機
管理大量主機的關鍵之一是,找到一些方法把物理機劃分成小塊。
傳統的虛擬化技術。標準的虛擬化技術包括AWS、VMWare、VSphere、Xen和KVM,其架構從底層到最上層是:機器、內核、主機操作系統、hypervisor、虛擬機(又包括內核、操作系統和應用)。其中的虛擬機可以安裝不同的操作系統,可被認為完全封閉的機器。Hypervisor會佔用CPU、I/O和內存等資源,開的虛擬機越多,hypervisor佔用的資源就越多。因此,物理機切分的越來越小的時候,收益也越小。
Vagrant。是一個部署平台,通常在開發和測試環境使用,而非生產環境。能幫助在本地機器上輕鬆創建類生產環境,可以同時創建多個VM,通過關閉幾個測試故障模式。缺點:開發機上會有更多的資源消耗。
Linux容器。Linux容器可以創建一個隔離的進程空間,進而在這個空間中運行其他的進程。最流行的是LXC。其架構從底層到最上層是:機器、內核、主機操作系統、容器(包含操作系統和應用)。容器運行的操作系統必須要和主機操作系統相同的內核。沒有了hypervisor,啟動速度更快。相同硬體上能比VM運行更多的數量的容器,資源利用更高效。容器也能很好地在虛擬機上工作。缺點:需要花費工作讓外界看到一台主機上的不同容器,並講外部請求路由到容器。容器的隔離性沒有VM好,某些容器進程可能會跳出容器,與其它容器進程或底層系統發生干擾。
Docker。構建在容器上的平台,進行容器管理,可以創建和部署應用。可以在Vagrant中啟動單個VM,其中運行多個Docker實例,每個實例包含一個服務。這樣在單機上開發和測試更便捷和省資源。CoreOS是專為Docker設計的操作系統,佔用資源更少。Google的開源工具Kubernetes和CoreOS集群能進行跨集群的Docker管理和調度。有個工具Deis(http://deis.io/),試圖像Heroku那樣在Docker上提供PaaS。
12. 一個部署介面
參數化的命令行調用是觸發任何部署的最合理的方式。需要包含微服務名字、版本和要部署的環境。Python庫Fabric可以講命令行調用映射到函數,也提供類似SSH的機制控制遠程機器。Ruby可以用Capistrano,Windows可以用PowerShell。
環境定義。對微服務配置,完成微服務到計算、網路和存儲資源之間的映射。可用YAML文件描述。例子中配置的資源包括:開發和生產環境下不同的節點名稱、資源大小、憑證(credential),服務以及節點個數;微服務中定義了運行的Puppet文件名稱、連接屬性(tcp,埠號,允許範圍)。構建定義系統工作量很大,Hashicorp有個工具Terraform可以幫助做這些事情。
13. 小結。服務要能夠獨立於其它服務部署。每個服務放到單獨的主機/容器中。自動化一切。推薦Jez Humble和David Farley的《持續交付》。
BrianZhang:《微服務設計》閱讀筆記(一)微服務BrianZhang:《微服務設計》閱讀筆記(二)演化式架構師BrianZhang:《微服務設計》閱讀筆記(三)如何建模服務BrianZhang:《微服務設計》閱讀筆記(四)集成BrianZhang:《微服務設計》閱讀筆記(五)分解單塊系統BrianZhang:《微服務設計》閱讀筆記(七)測試BrianZhang:《微服務設計》閱讀筆記(八) 監控BrianZhang:《微服務設計》閱讀筆記(九)安全BrianZhang:《微服務設計》閱讀筆記(十)康威定律和系統設計BrianZhang:《微服務設計》閱讀筆記(十一)規模化微服務BrianZhang:《微服務設計》閱讀筆記(十二完結篇)總結軟體開發之路推薦閱讀:
※哈希演算法集合類庫HashLib
※《微服務設計》閱讀筆記(七)測試
※《微服務設計》閱讀筆記(一)微服務
※輕鬆理解UML用例圖時序圖類圖的教程
※一個產品累積的測試用例越來越多,跑一次完全的回歸時間越來越長,如何有效管理巨量測試用例?