微服務架構如何結合DevOps做好持續交付
微服務架構如何和持續交付過程相結合,是我們在實施微服務架構的時候必須要考慮的問題,如果是一個簡單的單體應用的自動化編譯構建和發布,相對來說要簡單的多,但是在實施微服務架構后,整個持續交付過程本身會增加一定的復雜度。
我們舉一個供應鏈系統開發的場景來說明。
該供應鏈系統劃分為了門戶應用,招投標中心,采購中心,供應商中心,用戶中心和流程中心幾個大的微服務模塊。基于微服務架構本身進行模塊拆分的要求可以看到,以上的六個微服務模塊要做到完全的獨立自治,獨立的配置管理庫,并能夠獨立進行編譯構建打包測試和最終的版本發布操作,而最終的六個微服務模塊一起組成一個完整的供應鏈管理業務應用。
這個和多年前我們談到的私有云PaaS平臺里面的組件化開發思路是完全一樣的。基于這種微服務模塊劃分,我們來看如何和持續交付過程和DevOps支撐平臺相結合。
每個微服務模塊獨立進行配置和源代碼管理,獨立數據庫,獨立進行編譯構建和部署發布。
在這種思路下可以看到,我們首先要有應用集的概念,即本次構建的供應鏈管理就是一個大的應用集,但是這個應用集下面卻可以有多個微服務模塊。整個思路是要先構建一個獨立的應用集,并規劃應用集的版本。然后才是在應用集下面創建6個獨立的研發項目版本,分別對應上面的6個微服務模塊,并制定獨立的svn或git源代碼目錄分支。
針對每一個微服務模塊都要獨立創建編譯,構建,發布等任務,同時針對每一個微服務模塊創建一個獨立的從編譯構建測試到發布的流水線任務作業。該流水線每觸發執行一次,即可以完成該獨立的微服務模塊的自動化編譯構建打包,自動化的代碼檢查測試并發布到測試環境進一步供測試人員進行測試。
每一個微服務模塊只部署到一個Docker容器里面,不再進一步進行組件拆分部署到多個Docker容器中。但是容器本身可以在后期進行資源動態擴展。即微服微模塊編譯構建通過,打包制作鏡像到一個鏡像文件,并在后續對鏡像文件進行部署。
問題是在實際的DevOps支撐里面,可以考慮將打包和鏡像制作過程隱含掉,畢竟用戶并不關心該過程。
對于6個微服務模塊間有接口調用,在前面我們思路里面是內部6個模塊間的交互不用啟用API網關進行交互,而直接走微服務架構里面的服務注冊和配置中心即可。
在多模塊交互協同下,所有的微服務模塊在觸發自動編譯構建并部署后都需要自動化單元測試,這里面最重要的就是對接口的單元測試,這種單元測試包括南向接口和北向接口兩個部分的內容,只有兩部分單元測試都通過,該模塊本身才處于一種穩定可測狀態。
自動化單元測試不通過應該先開發進行檢查并解決,因此在多模塊分工下更加應該首先對規劃好的接口進行實現并發布,只有這樣才不會影響到其它模塊的并行開發工作。
最近我一直在思考,如果將整個持續交付過程規劃為研發過程管理工具和DevOps支撐平臺工具兩個工具平臺來支撐的話,實際上很多內容很難在兩個平臺間協同好。DevOps平臺更多是技術平臺,僅僅解決的是構建和發布過程,而實際上很難去解決我們說的多個組件間的協同和研發過程管理。
開發人員和測試人員,一種思路是測試人員手工執行流水線,在執行完成后進行測試操作;還有一種思路是開發人員去跑流水線,在自測沒有問題后提交測試。可以看到更好的做法應該是開發去跑流水線,提交測試后選擇已經完成的需求或修復的Bug,自動變更狀態。而測試人員只需要在測試環境對待驗證的問題進行測試和驗證就可以了。即只有問題狀態是待驗證,那么當前的測試環境版本一定就是可以驗證的一個版本。
開發人員的流水線為:
代碼更新-》編譯構建-》代碼檢查-》鏡像打包-》部署-》自動化單元測試-》人工驗證并提交測試
在人工驗證后提交測試,同時對相關需求和Bug的狀態進行變更。測試人員可以進入到測試環節。實際上我們大部分重復迭代都應該在這個階段,直到所有的需求全部實現,所有的Bug缺陷都關閉。
而基于上篇文章思考,在該流水線上可以再增加一個測試驗證環節,即測試驗證通過后自動進行環境遷移,將最新的版本發布到UAT環境以方便進行UAT測試操作。如果考慮到流水線松耦合,那么可以將測試驗證后發布UAT環境作為一個獨立的流水線,即:
選擇鏡像(可以選擇多個鏡像)-》配置修改-》發布生產環境
在這個過程中鏡像從鏡像庫選擇,對應到當前項目的最新基線版本(基線版本為測試通過后的版本),即在開發流水線上仍然需要增加了一個打基線標簽的人工操作,這個可以由測試人員來完成。
開發構建,發布和SIT測試是單微服務模塊視角。但是整體的應用版本規劃,UAT測試則是全應用集視角。即不論是新增還是后續變更版本的規劃,我們都希望能夠看到整個應用集的視角,包括這次變更究竟影響到哪些微服務模塊,哪些會重新構建或發生版本變化,這些都必須清楚。
如果一個功能變更導致我們所有的微服務模塊都必須重新編譯構建和發布,那么我們進行微服務模塊拆分,按微服務方式獨立自治管理的目的就根本沒有達到。一個簡單的原則就是影響到哪個模塊就哪個模塊進行更新,如果影響到接口,就接口對應的模塊也配套更新。可見微服務模塊間的接口一定得松耦合,如果拆分為微服務模塊,但是之間的接口交互異常復雜,那么仍然是強耦合關系,沒有意義。
唯一需要說明的是一種變更是變動了底層基礎組件的接口規格,那么這種情況下往往才會出現大量的微服務模塊都出現重新編譯構建。基礎組件變更,如果接口沒有變更,那么上層的應用組件同樣不應該重新構建,即相互之間應該是基于服務接口的依賴,而不能是基于Jar包的依賴。Jar包依賴容易導致的問題就是在使用Maven的時候會觸發自動的重新編譯構建操作。
從部署到DEV環境,再到部署到SIT環境,再到部署到UAT環境,整個過程必須進行全程跟蹤。形成基于當前項目版本的可視化追蹤視圖。這個功能實際在持續集成的時候也是必備的關鍵功能。