微服務之部署

如何在細粒度的架構中更好的微服務。這裏會從持續集成和持續交付提及。linux

1.持續集成簡介安全

CI(Continuous Integration , 持續集成)服務器

CI可以保證新提交的代碼與已有的代碼進行集成,從而保證全部人保持同步。CI服務器會檢測到網絡

代碼已提交併簽出,而後花些時間來驗證代碼是否經過編譯以及測試可否經過。架構

做爲這個流程的一部分,咱們常常會生成一些構建物(artifact)以供後續驗證使用。微服務

理想狀況下,這些構建物應該只生成一次,而後在本次提交所對應的全部部署環節中使用。工具

 

CI的好處不少。經過它,咱們可以獲得關於代碼質量的某種程度的快速反饋。測試

CI能夠自動化生成二進制文件。用於生成這些構建物的全部代碼都在版本的控制之下,spa

因此若是須要的話,能夠從新生成這個版本的構建物。經過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.環境

相關文章
相關標籤/搜索