今年一直在公司實踐CI,本文將近半年來的一些實踐總結一下,可能不太完善或優美,但的確初步解決了我目前所在項目組的一些痛點。當然這僅是一家之言也不夠完整,后續還會深入實踐和引入Kubernetes進行容器編排,以及通過阿里雲K8S服務進行高效的雲上托管,希望對各位童鞋有一點用。
一、持續集成全流程介紹
今年一直在開發我司的一個核心業務系統,一個還未上線的產品開發階段,其中后端采用ASP.NET Core + 一系列開源組件開發微服務並且部署在Linux Docker中,前端采用React + Flutter開發Web和App。采用了Jenkins作為CI工具,集成了一堆插件Plugin實現了初步的持續集成全流程。
下圖就是我最近整理的一個目前的持續集成全流程圖:

可以看出,在開發測試環境我有3個環境:
(1)DEV環境:用於dev分支的前后端開發聯調,有單獨的數據庫
(2)MT環境:用於release分支(現階段我直接用的master分支,產品上線后不可取)的測試進行集成測試,有單獨的數據庫
(3)DEV-AT環境:用於dev分支的自動化接口測試環境,即專門拿來跑自動化接口腳本的環境,有單獨的數據庫
針對CI服務器,在開發測試環境我有個2個節點:
(1)master節點:用於持續集成和部署等一般性構建任務
(2)slave-at節點:專門用於跑自動化接口測試腳本構建任務
推薦在Jenkins中為不同類型的構建任務設置不同的label,這樣可以綁定不同類型的構建任務至不同的Node上執行,從而減少高峰時期master節點的負載壓力。
二、ASP.NET Core CI流程部分
我的后端微服務是基於ASP.NET Core開發的,采用了容器化部署至Linux服務器,之前有過一篇詳細的文章介紹過《基於Jenkins Pipeline的ASP.NET Core持續集成實踐》。

在Jenkins中提供了Pipeline方便地進行構建流水線,在我的實踐中主要是通過開發人員的每一次Check-In到git,觸發一個Webhook到Jenkins中從而使持續集成構建任務開始執行:

從圖中可以看出,其經歷了中台微服務的編譯和單元測試 及 BFF(Backend for Frontend)服務的編譯和單元測試來保障代碼質量,當然前提是有足夠的單元測試作為保護層,這也需要開發人員花時間為每個服務接口(或者高價值的部分)寫單元測試!
如果構建任務中有一個Stage失敗了,那么此構建任務則認為失敗,會給開發團隊和Leader發送郵件告警:

此外,我們還使用了一個用於大屏顯示構建狀態的插件—Build Monitor,在我們工作區后方的電視屏上會顯示各個構建任務的實時狀態,如果有任務失敗了會變為紅色:

並且,Build Monitor還會將推進不可靠代碼的提交者名字(git賬號名字)顯示在屏幕中的構建任務里邊,方便大家查看誰的鍋:

三、ASP.NET Core CD流程部分
經過CI部分,就可以初步認為提交的代碼已經經過了初步的驗證,這時會進入部署部分的構建任務,在我的流程里會有開發聯調環境的部署及接口自動化環境的部署。當然,除了API的部署也有Web的部署,我們可以將其寫到一個統一的Pipeline中也可以分開兩個Pipeline來寫。
下圖是我的一個API的部署構建任務,其中會經歷中台微服務的部署及BFF服務的部署,當然也可以部署至多個服務器:
這里說一下,由於我目前並沒有采用任何的容器編排工具,所以這里的發布就只是單純的將release文件覆蓋之后然后將docker暫停和重啟。這樣做的缺點是沒有充分利用鏡像的優點,無法實現版本的有效管理(比如回退)。
四、RobotFramework AT流程部分
對於一個產品來說,質量很重要,而保證質量的輔助手段就是充分的回歸測試。自動化接口測試使得回歸測試成為可以頻繁觸發,也就能及時發現提交的代碼對已有接口功能的影響。我們的AT是根據重要的業務場景來寫的,而且我們也覺得AT應該寫在那些主要業務流程的接口上面,才能顯示出它的價值,而且AT的編寫也是不小的工作量。
我們使用的是RobotFramework,開發語言是Python。在開發人員提交代碼並發布到開發聯調環境時,便會自動觸發AT環境的部署,部署無誤后就會觸發AT任務的執行,AT執行無誤后才會自動Merge dev分支的代碼至穩定的測試分支,之后測試再選擇是否發布最新的更改至測試環境進行驗證bug fix。
下圖是基於RF的AT構建任務的執行結果:

下圖是該任務的具體的輸出信息,我們可以看到每個用例的執行情況:

由於我目前對這塊了解不多,后續有機會了解多點后可以介紹一點我們在AT方面的實踐和規范。
五、小結
本文介紹了我目前團隊所在使用的持續集成全流程及一些重要插件的使用,雖然還很不完善,但初步解決了我所在團隊在集成和發布上的一些痛點。隨着后續對K8S的學習的深入,我會逐步引入K8S進行微服務的容器編排以及持續集成的K8S化改造,希望到時再進行分享。
