DevOps平台架構演進


附最新架構圖 https://www.processon.com/view/5cbd897de4b0bab90962c435

導讀

系統架構是一個系統的靈魂,然而一個好的架構(或者更確切的說,一個合適的系統架構)不是一蹴而就,一下子就能完全設計出來的,而是隨着系統發展,逐步演進的。本文將介紹明源雲研發協同平台的架構從0到1,逐步隨着業務發展一步一步迭代演進的過程。

背景

隨着公司的ToB業務發展,開發團隊規模不斷擴大,需要交付的業務也不斷增長,在這個過程中,交付的效率和質量出現了不同程度的問題,雖然也有QA團隊制定的流程規范以及一些相應的保障措施,但是在交付壓力下,效果不那么盡如人意。在此背景下,研發協同產品被提上日程,最初的目的就是為了提升整個交付鏈條的效率和質量。研發協同平台提供從“需求->開發->構建->代碼質量->測試→發布”的全鏈路的一站式服務,基於敏捷研發、持續集成、持續交付、DevOps等研發理念,主要是為開發團隊賦能,提升交付效率和質量。

技術選型

技術選型是一個項目的基礎,一旦技術選型出現問題,后期要換用其他技術棧,代價是非常大。一般情況下,技術選型會遵循以下幾個原則:

  • 選擇熟悉的技術 - 一個新項目最好不要使用超過 30% 的新技術,對於不誰的技術,不可能控制使用過程中出現的風險。而且從團隊建設上,任何一位技術 Leader,如果不能得到下屬的技術尊重,必將受到懲罰。當然也不能完全不用新技術,完全不用,勢必會走向走向另一個極端,裹足不前,失去技術前進的機會。總的來說,選擇熟悉的技術,保持穩定性,同時適當引入新技術,保持技術先進性。
  • 選擇成熟活躍的技術 - 選擇成熟的技術,可以避免踩不必要的坑,碰到問題,也可以找到豐富的資料,也可以得到更多的社區支持。當然這是針對應用場景而言,也有一些團隊專門就是做新技術預研,專門去踩坑,看是否有應用新技術的可行性。技術不光是考慮成熟度,還要考慮技術活躍度,活躍度在某個角度也間接說明了技術的應用廣度,同時也能得到更多的支持。
  • 選擇前進的技術 - 選擇一個技術的最低標准是,技術的生命周期必須顯著長於項目的生命周期。為什么需要確保所選擇的技術不斷前進?因為當前技術發展是非常快速的,技術的前進不僅僅取決於它本身,也和大環境發展密切相關。例如早期的delphi, silverlight, 現在都已被淘汰,如果不幸選擇了類似這樣的技術棧,對項目的傷害是巨大的,甚至可能直接導致項目無法進行下去。總的來說,好的技術棧要永遠跑在用戶需求前面。

基於以上的技術選型原則,研發協同平台的技術選型如下:

  • 應用技術選型:.Net Core, ABP, EF Core,SQL Server
    選型理由:團隊開發人員都是.NET開放背景,.Net Core 2.0已發布,已經比較成熟穩定,相較於.Net Framework,不僅跨平台,而且開源,社區活躍度相當高。ABP是一個開源的.NET/.NET Core的基於DDD的快速應用開發框架,社區活躍度高,版本迭代快,一直在向前。最重要的一點,是這些技術棧都有團隊成員有成功的實施經驗。
  • CI/CD工具鏈技術選型
    需求管理 - JIRA
    代碼托管- Gitlab, sourcetree
    持續集成 - Jenkins, webpack, grunt
    持續部署 - docker
    質量服務 - sonarqube, dotcover, nuint, xunit, jmeter,selenium
    選型理由:團隊除了在docker上的應用經驗有所不足外,其他的技術都是非常成熟的。docker技術,團隊雖然也有一定的技術基礎和應用經驗,但沒有像研發協同這種大規模的生產應用,並且要同時支持windows和linux容器。研發協同平台的產品特性決定了,會有大量開發團隊的測試環境運行在平台下,docker是最符合產品需求的技術。所以即使有風險,也必須選擇docker,同時也是必須啃下的骨頭。

單體架構

在項目初期,為了產品快速上線、快速驗證,架構是比較簡單直接的,就是單體架構,如下圖:

單體架構實現了主要的核心功能,提供了一站式的從需求->代碼管理->開發->持續集成的服務。整體架構就是展示層->應用服務->數據層,其中緩存,后台作業,調度,郵件,日志,權限控制等都是以功能模塊的形式內嵌在應用服務中,對於在CI過程使用到的工具棧,也是直接調用第三方的服務。另外因為CI過程一般都是長時任務,對於在展示層顯示CI的過程狀態,也是采用了簡單的輪詢機制來處理。
單體架構快速了實現了產品的核心功能,可以提供給種子用戶快速驗證,但隨着驗證反饋->快速迭代,一旦產品提供給大范圍的用戶使用,這種架構也就不在滿足需求了,它的主要問題如下:

  • 業務服務和基礎功能服務耦合在一起,一方面影響業務服務的擴展,另一方面基礎服務是公共的,除了為RDC平台提供服務,在技術上也需要為其它產品提供服務
  • 業務服務中有不少長耗時的任務,這些都影響了業務服務的橫向擴展,長耗時任務也必須從業務服務解耦
  • 輪詢機制的狀態刷新需要改進,同時應用服務和基礎服務拆分后,也需要機制保障通信,缺少消息服務中間件
  • 不管是從穩定性還是可用性考慮,服務都必須可擴展
  • 一旦大范圍使用,Jenkins單點,docker單點服務,都不足以應對,一定要集群

面對上述問題,平台的架構也必須升級來滿足業務業務發展的需求,而演進的主要方式則是服務化、集群化

架構演進的五條原則

既然要對架構進行升級重構,那么有沒有一些基本的准則,指導我們避免一些坑呢?基於此,我們嘗試總結了架構演進的五條原則:

  • 確定當前的架構現狀:每次架構演進,一定是針對當前架構的,所以必須非常清楚當前的架構現狀和問題。清楚現狀,明白目標,才能逐步改進,向目標前進。
  • 確定重構的目的和必要性:架構重構的原因是什么?是為了滿足業務需要還是只是覺得架構比較落伍?除了架構重構之外,是否有別的備選方案,是否一定要進行架構重構?
  • 定義“重構完成”的標准:為每一次架構演進定義清晰的重構目標和成功標尺。
  • 漸進式重構:盡量將重構過程進行分解,每次都進行小的改進,盡快展示成果並得到反饋,在迭代中逐步完善。
  • 遠離虛的東西:例如使用熱門的技術,使用不成熟的技術。架構重構要腳踏實地,根據實際需要以及團隊的技術背景,合理的選擇重構方案。

我們每次對架構的重構,都是按照這些原則來進行的。

向集群架構演進

單體架構有不少問題,但是否一定需要進行架構重構呢?在重構前,我們需要回答架構演進原則提出的問題:

  • 確定當前的架構現狀:所有服務集中在一起運行。
  • 確定重構的目的和必要性:隨着產品的逐步推廣,使用用戶增多,使用頻率,單體架構在應對業務量上漲上已經越來越吃力,同時,可用性也成為了高風險點。
  • 定義“重構完成”的標准:讓架構支撐服務化,集群化。
  • 漸進式重構:以迭代的方式,按優化級逐步重構。例如,jenkins集群化,docker集群化,基礎服務解耦服務化,一步一步,每一步都可以看到效果,得到反饋。
  • 遠離虛的東西:並沒有引入多少新的東西,主要是解耦,服務化,集群,增加消息服務中間件。

除了原有的架構重構外,在產品層面, 整個交付鏈條延伸到了C/D環節,這里和其他DevOps平台一個很不一樣的點就是,在研發協同平台上交付的產品是ERP產品,ERP產品是運行在大量客戶的不同環境下的,它不是交付一個SaaS產品,一個雲服務產品。ERP產品要持續交付給大量的不同客戶,而這里的客戶環境又各不相同,要做到穩定,持續的交付是有相當大的難度和挑戰的,在架構設計上必須充分考慮C/D的穩定性和持續性。

基於以上的需求,我們將單體架構重構為集群架構,並增加了C/D的架構設計,架構圖如下:

集群架構有如下特點:

  • 解耦了基礎服務與業務服務,各個服務的職責更清晰,也更單一
  • 基礎功能服務化,復用基礎服務能力
  • 使用Azure文件雲服務,提高文件服務的可靠性和可用性
  • 新增消息服務,解耦各組件之間的通信
  • 構建服務集群,提高服務的可靠性和可用性
  • 構建Jenkins集群,提高平台的持續集成能力
  • 構建docker服務集群,提高平台持續部署,持續提供穩定運行環境的能力

實現了集群架構以后,服務的能力,穩定性和可靠性都上了一個台階,但是隨着用戶的使用越來越深入,平台提供的服務越來越多,集群架構的問題也逐步開始顯現:

  • 平台提供的服務能力越來越多,業務越來越復雜
  • 服務雖然集群化,但是業務服務能力還是單一對外,某個服務功能出現問題,會影響到服務整體對外提供的能力。可行的途徑是進行服務拆分,不過服務拆分,復雜度也會增加,服務的運維成本以及治理問題也是需要綜合考慮的
  • docker容器采用自開發的集群分配策略,缺少編排能力
  • 平台服務要提供集成與被集成的能力,與其他的CI服務集成,與測試平台集成
  • 平台要與其他產品打通 - 與運維產品打通,獲取客戶運維數據,做到DevOps閉環,通過反饋和運維數據反向推動產品持續迭代改進
  • 平台要對外開放,面向生態合作伙伴提供服務能力,對外開放,第一步就是要讓用戶能進來,這就涉及到整個用戶中心體系的建立,用戶管理、統一身份認證等。
  • 雖然集群架構已大大提高了可靠性和可用性,但是隨着服務的深入使用和用戶規模的不斷增長,對可靠性和可用性的要求也越來越高,對平台服務以及服務資源的運維也變得越來越重要和緊迫

面對上述問題,需要對服務進行拆分,治理,提供服務和資源的運維、監控能力,而都需要架構

向微服務架構演進

在進行微服務架構重構之前,我們同樣需要回答架構演進原則提出的問題:

  • 確定重構的目的和必要性 - 隨着產品的持續迭代,業務復雜度越來越大,服務的使用也越來越深入,用戶規模也在不停的增長,對整體服務的可靠性,可用性提出了新的挑戰
  • 定義“重構完成”的界限 - 微服務化,容器雲平台
  • 漸進式重構 - 以迭代的方式,按優化級逐步重構。例如服務的運維,監控,日志服務,服務的拆分,治理,容器雲平台這些都是獨立可逐步改進的
  • 確定當前的架構狀態 - 集群架構中已經詳細的描述
  • 遠離虛的東西 - 新引入的技術點都有成熟可借鑒的方案,例如k8s,ELK,grafana, IdentityServer4,Ocelot,Consul

但是這里有一點是要特別強調的,盡管新引入的技術都有成熟可借鑒的方案,但是對團隊而言,有不少是沒有成功的生產環境實施經驗的,這里是冒了一定的風險,但又是不得不去做和突破的事情。
重構后的微服務架構圖,如下:

微服務架構的特點如下:

  • 提煉CI引擎,豐富集成能力
  • 服務按領域拆分,提供服務治理能力
  • 服務運維能力,提供監控、告警、統計分析
  • 提供日志服務,便於錯誤分析和運營分析
  • 提供統一的容器雲服務, 提供高可用、可伸縮的容器應用管理

各個應用層在微服務架構下的職責:

  • 運行環境層:提供基礎設施服務,包括服務器,IT安全配置以及容器雲平台。未來所有的服務都會運行在容器雲平台上,當前只有少數的服務在容器雲平台上試運行,隨着不斷的改進、成熟,未來會逐步將服務遷移到容器雲平台上
  • 數據存儲層:提供數據存儲能力,對於不同的數據類型,提供了不同的存儲方式。 Sql Server用於應用數據的存儲,redis用於緩存數據的存儲,ES集群用於日志的存儲,Azure文件用於文檔的存儲
  • 基礎服務層:提供基礎公共服務能力,除了為研發協同平台本身提供基礎服務,也面向其他產品提供基礎服務能力。
    日志服務(ELK)提供日志采集,存儲,分析和展示服務;
    消息服務(MQTT)提供組件間的通信能力;
    文件服務(Azure文件)為應用提供統一的上傳、存儲、下載的服務;郵件服務提供郵件發送服務;
    任務調度和后台作業(Quaz+Hangfire)提供了長耗時任務隊列的調度和處理服務;
    身份認證服務(IdentityServer4)面向開放提供了統一的身份認證能力。
  • 應用服務層:研發協同業務服務,主要包含基礎服務,產品服務,持續集成服務、質量服務和持續交付服務。當前應用服務還沒有微服務化,還處於服務拆分階段,按領域拆分,按文件結構組織,一旦微服務框架就緒,則按領域服務一個一個拆分,逐步切換。
  • API接口層:API網關為服務消費端提供了統一的服務入口。除了網關,實現微服務框架,還必須實現服務治理:服務的注冊、發現、負載、容錯、降級、監控與日志。
  • 展示層:展示層是應用服務的消費者,通過API網關來使用應用服務。
  • 運維監控:運維監控服務(App.Metric+telegraf+InfluxDB+Grafana)當前主要實現了服務器資源監控以及業務服務的監控(流量、請求、錯誤等),以及分析圖表的展示,並根據一定的預警規則,即使預警異常。

微服務架構是我們今年技術規划要實現的目標,其中一部分已經落地,一部分正在進行,也有一些還未開始,隨着產品業務的發展,伴隨着架構也是在不斷摸索、重構、演進、向前。

寫在最后

從來沒有一個完美的架構能夠一直支撐業務的發展,架構是動態的、變化的,隨着業務的發展不斷演進的,不同的階段需要不同的架構 。研發協同平台的架構也是經歷了單體架構->集群架構->微服務架構幾個階段,而且每一次架構重構周期都比較長,只要架構的模式思路定下來,保持快速的敏捷演進,不停向前,結合反饋和實際應用情況,不斷改進,就可以比較穩定的實現架構重構。

附最新架構圖


免責聲明!

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



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