微服務之部署


如何在細粒度的架構中更好的微服務。這里會從持續集成和持續交付說起。

1.持續集成簡介

CI(Continuous Integration , 持續集成)

CI能夠保證新提交的代碼與已有的代碼進行集成,從而保證所有人保持同步。CI服務器會檢測到

代碼已提交並簽出,然后花些時間來驗證代碼是否通過編譯以及測試能否通過。

作為這個流程的一部分,我們經常會生成一些構建物(artifact)以供后續驗證使用。

理想情況下,這些構建物應該只生成一次,然后在本次提交所對應的所有部署環節中使用。

 

CI的好處很多。通過它,我們能夠得到關於代碼質量的某種程度的快速反饋。

CI可以自動化生成二進制文件。用於生成這些構建物的所有代碼都在版本的控制之下,

所以如果需要的話,可以重新生成這個版本的構建物。通過CI我們能夠從已部署的構建物回溯到

相應的代碼,有些CI工具,還可以使這些代碼和構建物上運行過的測試可視化。

 

持續集成允許我們更快速,更容易的修改代碼。

有人任務使用了CI工具就算采用了CI這個實踐,事實上,只有工具是遠遠不夠的。

測試別人是否真正理解CI的三個問題?

  • 你是否每天簽入代碼到主線?

你應該保證代碼能夠與已有代碼進行集成

  • 你是否有一組測試來驗證修改?

如果沒有測試,我們只能知道集成后沒有語法錯誤,但無法知道系統的行為是否已經被破壞。

沒有對代碼行為進行驗證的CI不是真正的CI。

  • 當構建失敗后,團隊是否把修復CI當做第一優先級的事情來做?

綠色的構建意味着,我們的修改已經安全地和已有代碼集成在了一起。紅色的構建意味着,最后一次修改很可能有問題,

這時只能提交修復構建的代碼。

2.把持續集成映射到微服務

前面已經提到過,每個微服務應該能夠獨立於其他服務進行部署。

所以如何在微服務、CI構建及源代碼三者之間,建立起合適的映射呢?

最簡單的做法,如下

 

 圖 6-1 把所有微服務放在同一個代碼庫中,並且只有一個構建

這種方法從表面上看比其他方法要簡單的多:因為你需要關心的代碼庫比較少,

而且從概念上來講,這種構建也比較簡單。開發者的工作也得到了簡化:

我們只需要提交代碼即可,如果需要同時在多個服務上工作的話,一個提交就能搞定。

 

在同步發布(lock - step release)中,你需要一次性部署多個服務。

一般來講,我們絕對應該避免這個模式,但是在項目初期是個例外。

當僅有一個團隊在所有的服務上工作時,這種模式在短時間內是可接受的。

 

這種模式存在很多明顯的缺點。

如果我僅修改了圖6-1中用戶服務中的一行代碼,所有其他服務都需要進行驗證和構建,

而事實上它們或許並不需要重新進行驗證和構建,所以這里我們花費了不必要的時間。

更糟糕的是,我不知道那些構建物應該被重新部署,哪些不應該。

使用這種方式的組織,往往都會退回到同時部署所有代碼的模式,而這也正是我們非常不想看到的。

很不幸,如果這一行的修改導致構建失敗,那么在構建得到修復之前,其他服務相關的代碼也無法提交。

這種方法的一個變體是保留一個代碼庫,但是存在多個CI會分別映射到代碼庫的不同部分。

如圖 6-2

 

 這種模式是個雙刃劍。

一方面它會簡化檢出/檢入的流程,但是另一方面,它會讓你覺得同時提交對多個服務的修改

是一件簡單的事情,從而做出將多個服務耦合在一起的修改。

但是相對於只有一個構建的多個服務來說,這個方式已經好很多了。

 

還有一種比較好的方式,每個微服務都有自己的CI,這樣就可以將該微服務部署到生產環境之前做一個快速的驗證。

如圖6-3

 

 

這里的每個微服務都有自己的代碼庫,分別於相應的CI綁定。

當對代碼庫進行修改時,可以只運行相關的構建以及其中的測試。

 

每個微服務都有自己的代碼庫和構建流程。

我們也會使用CI構建流程,全自動話的創建出用於部署的構建物。

3. 構建流水線和持續交付

把一個構建分成多個階段是很有價值的。

因為有的測試運行快,涉及范圍小,有的測試運行耗時,涉及范圍廣,

如果放一起,快速如果失敗,還會接着運行耗時的測試,這樣就不合理。

解決這個問題的一個方案是,將構建分解成為多個階段,從而得到我們熟知的構建流水線

在第一個階段運行快速測試,在第二個階段運行耗時測試。

 

構建流水線可以很好的跟蹤軟件構建進度:每完成一個階段,就離終點更近一步。

流水線也能夠可視化本次構建物的軟件質量。構建物會在整個構建的第一個環節生成,

然后會被用在整個流水線中。

 

CD(Continuous Delivery, 持續交付)基於上述概念,並在此之上有所發展。

CD能夠檢查每次提交是否達到了部署生成環境的要求,並持續地把這些信息反饋給我們,

它會把每次提交當成候選發布版本來對待。

為了更好的理解這些概念,我們需要對從代碼提交及部署到生產環境這個過程中,所需要經歷的流程進行建模,

並知道哪些版本的軟件時可發布的。

 

 UAT(User Acceptance Testing, 用戶驗收測試)流程。

通過對整個軟件上線過程進行建模,軟件質量的可視化得到了極大改善,這可以大大減少發布之間的間隔,

因為可以在一個集中的地方看到構建和發布流程,這也是可以引入改進的一個焦點。

 

在微服務的世界,我們想要保證服務之間可以獨立於彼此進行部署,所以每個服務都有自己獨立的CI.

不可避免的例外

所有好的規則都需要考慮例外。

當一個團隊剛開始啟動一個新項目時,尤其是什么都沒有的情況下,你可能會花很多時間來識別出服務的邊界。

所以在你識別出穩定的領域之前,可以把初始服務都放在一起。

在最開始的階段,經常會發生跨服務邊界的修改,所以時常會有些內容移入或者移出某個服務。

在這個階段,把所有的服務都放在一個單獨的構建中,可以減輕跨服務修改所帶來的代價。

當然,在這個階段你必須把所有服務打包發布,但這應該是一個過渡步驟。

4.平台特定的構建物

大多數技術棧都有相應的構建物類型,同時也有相關的工具來創建和安裝這些構建物。

Ruby中有gem,Java中有JAR包和WAR包,Python中有egg。

 

但是,從微服務部署的角度來看,在有些技術棧中只有構建物本身是不夠的。

所以為了部署和啟動這些構建物,需要安裝和配置一些其他軟件,再啟動這些構建物。

 

自動化可以對不同構建物的底層部署機制進行屏蔽。

5.操作系統構建物

有一種方法可以避免多種技術棧下的構建物所帶來的問題,那就是使用操作系統支持的構建物。

舉個例子,對基於RedHat或者CentOS的系統來說,可以使用RPM;對於Ubuntu來說,可以使用deb包;

對於Windows來說,可以使用MSI。

 

使用OS特定構建物的好處是,在做部署時不需要考慮底層使用的是什么技術。只需要簡單使用內置的工具就可以完成軟件的安裝。

OS包管理工具,可以幫你完成很多原本需要使用Chef或者Puppet來完成的工作。

 

其缺點是,剛開始編寫構建腳本的過程可能會比較困難。

當然,還有另一個缺點,即如果你需要部署到多個操作系統的話,維護不同版本構建物的開銷就會很大。

 

但如果軟件時部署在你可控的機器上,那么建議,盡量減少需要維護的操作系統的數量,最好只維護一種。

它可以大大減少不同機器之間可能存在的不同之處,並減小部署和維護的工作量。

 

特別是如果你在linux上工作,而且采用多種技術棧來部署微服務,那么這種方法就很合適。

6.定制化鏡像

使用類似Puppet、Chef及Ansible這些自動化配置管理工具的一個問題是,需要花費大量時間在機器上運行這些腳本。

 

什么是藍綠部署

藍綠部署允許我們在老版本服務不下線的同時,去部署新版本的服務。可以減少在部署時,服務停止的時間增加。

 

一種減少啟動時間的方法是創建一個虛擬機鏡像,其中包含一些常用的依賴

現在你可以把公共的工具安裝在鏡像上,然后在部署軟件時,只需要根據該鏡像創建一個實例,

之后在其上安裝最新的服務版本即可。

 

 你只需要構建一次鏡像,然后根據這些鏡像啟動虛擬機,不需要再花費時間來安裝相應的依賴,

因為它們已經在鏡像中安裝好了,這樣就可以節省很多時間。如果你的核心依賴沒有改變,

那么新版本的服務就可以繼續使用相同的基礎鏡像。

 

這個方法也有些缺點。

首先,構建鏡像會花費大量的時間

其次,產生的鏡像可能會很大。例如,當你創建VMWare鏡像時,在網絡上傳送一個20GB的鏡像文件會怎么樣。

由於歷史原因,構建不同平台上的鏡像所需的工具是不一樣的。

6.1 將鏡像作為構建物

們可以把服務本身也包含在鏡像中,這樣就把鏡像變成了構建物。

就像使用OS特定軟件包那樣,可以認為這些VM鏡像時對不同技術棧的一層抽象。

我們不需要關心運行在鏡像中的服務,所使用的語言是Ruby還是Java,最終構建物是gem還是JAR包,

我們唯一需要關心的就是它能否工作。

這個簡潔的方法有助於我們實現另一個部署概念:不可變服務器。

6.2 不可變服務器

通過把配置都存到版本控制中,我們可以自動化重建服務,甚至重建整個環境

但是如果部署完成后,有人登陸到機器上修改了一些東西呢?

這就會導致機器上的實際配置和源代碼管理中的配置不再一致,這個問題叫做配置漂移

為了避免這個問題,可以禁止對任何運行的服務器做手動修改。

相反,無論修改多么小,都需要經過構建流水線來創建新的機器。

7.環境

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM