大規模微服務場景下灰度釋出與流量染色實踐

劉超的通俗雲端計算發表於2022-12-08

本文內容選自中國DevOps社群年會 · 2019年會,劉超老師分享的《大規模微服務場景下灰度釋出與流量染色實踐》實錄。

大家好,我的題目叫《大規模微服務場景下的灰度釋出與流量染色實踐》。最近微服務很熱,與微服務相關的架構、流程、DevOps都很熱。

大規模微服務場景下灰度釋出與流量染色實踐

很多公司,包括傳統企業,到網際網路公司做交流的時候,會問道,你們網際網路公司號稱能夠加速業務創新、快速迭代,那我們是否也可以引入類似這樣的機制。

我們做微服務,主要分為兩個方面,一個是業務方面,另一個是技術方面。最下面是運維部,不過現在我們的運維部已經擴充成雲端計算,DBA裡的資料管理部門,已經發展成大資料,於是就有了技術中臺和資料中臺,另外還有共享使用者中心的業務中臺,總體構成了下層的中臺部門,在上層業務一定要做微服務化。業務和技術互相合作,做到加速創新的效果。

大規模微服務場景下灰度釋出與流量染色實踐

有很多人說,我們也上了微服務,但是會發現上微服務以後,看起來很好的東西,為什麼用起來一團亂麻。

我們拜訪過很多業界同仁,發現實施微服務之後,有以下痛點:

務依賴管理:服務間直接呼叫,依賴混亂微服務越來越多,自己理不清楚,不知道上線時會影響誰,上線後誰影響我,到底該什麼時候上線,依賴混亂的時候,沒辦法解決這些問題。

服務呼叫統計:呼叫記錄無跡可尋,呼叫統計與分析無從談起

服務介面規範:環境與介面規範缺失,維護困難

服務安全管理:安全靠白名單各自為戰

服務治理能力:大量重複程式碼 實現路由,分流,熔斷,降級

服務介面測試:拆分過程中介面行為不一致,隱藏Bug

服務灰度釋出:上線功能實現灰度藉助大量if-else

服務壓力測試:對於峰值壓力無歷史資料,靠運氣

服務呼叫鏈分析:當服務請求緩慢,難以定位問題點

測試環境治理:測試環境多,難管理,不可能100個容器每組一套

大規模微服務場景下灰度釋出與流量染色實踐

我們發現大家對微服務有很多誤解。比如,一般做微服務的時候,很多人都會問微服務怎麼拆,告訴我一個拆的最佳的實踐,但是其實,根據我們的實踐來講,微服務不僅僅是微服務拆分,微服務拆分只是十二個要點的其中之一。

十二個要點分別是:

  1. 微服務化的基石:持續整合

  2. 靜態資源分離與接入層設計

  3. 應用層設計之無狀態化與容器化

  4. 應用層設計之服務的拆分,發現與編排

  5. 效能最佳化之資料庫設計與橫向擴充套件

  6. 效能最佳化之快取的設計與橫向擴充套件

  7. 效能最佳化之訊息佇列與非同步化設計

  8. 服務的熔斷,降級,限流設計

  9. 配置中心的設計與實踐

  10. 統一日誌中心的設計與實踐

  11. 全鏈路應用監控實踐

  12. 服務的全鏈路壓測實踐

我們建議,先把前三個基礎打好,再進行拆分,而不是什麼技術、平臺、工具都沒有,直接把自己的傳統應用拆得七零八落。同時,值得再強調的是第一條,微服務化的基石:持續整合。微服務絕不是讓大家關起門來用三個月的時間拆出來,就直接上線。而是應該不斷地整合、迭代,是漸進式的模式。另外,微服務也不僅僅是個技術問題,它還涉及到IT架構、應用架構、組織架構的改變。

大規模微服務場景下灰度釋出與流量染色實踐

接下來給大家講一下網易微服務和DevOps的實踐過程。

我們整個DevOps,也是經歷了幾個過程。第一個和大家都一樣,當服務比較少的時候,開始手工化的方式,後來手工不行了就變成了指令碼化的方式,再後來因為開源有很多的工具可以用,變成了工具,而後變成一個平臺,最後變成一個統一的DevOps的平臺。

大規模微服務場景下灰度釋出與流量染色實踐

首先,第一個階段就是手工化。可能很多企業一開始都會存在這樣的階段,開發和運維之間的隔閡比較嚴重,老死不相往來。開發負責寫程式碼,線上的運維、釋出,以及SLA的保障,都是運維進行管理的。由於服務相對比較少,用物理機部署,基本上是一個單機應用加一個Oracle就可以搞定。

大規模微服務場景下灰度釋出與流量染色實踐

後來,隨著業務的發展,服務越來越多。這個模式和原來還是沒有變,開發和運維部的隔閡依舊存在。但是,運維發現接的需求越來越多,需要部署越來越多,需要一個環境隔離的方式,因此一般會上一個虛擬化系統,業內主流是用Vmware。這時候的部署方式一般是,Oracle部署在物理機上,其他業務系統都是部署在VMware上。部署東西多了,運維開始使用批次指令碼試圖解放人力,這屬於第二個階段-指令碼化的階段。虛擬化帶來很多的優點,比如,粒度靈活,隔離性得到一定保證,不會在一臺伺服器上部署很多東西。

但是這個階段也有非常多的問題。比如說釋出指令碼、邏輯相對複雜,時間長了以後,邏輯是難以掌握的。而且,如果你想把一個指令碼交給另外一個人,也很難交代清楚。

另外,並且指令碼多樣,不成體系,難以維護。線上系統會有Bug,其實發布指令碼也會有Bug。

虛擬機器大量地依賴於人工的排程,需要運維人員非常清楚,要部署在什麼地方。另外VMware還有一個問題,它使用共享儲存,會限制整個叢集的規模,因為此時的應用不多,這個程度的規模還可以接受。

線上的高可用性,業務層的開發人員不會做任何事情,他認為是線上一旦出事,應該由運維集中處理,迫使運維服務的釋出人員依賴虛擬化機制,來提供高可用機制。我們都知道VMware有非常著名的簡化運維的高可用機制,比如FT、HA、DR等類似的機制。如果我們是從IT層來做高可用,有一個缺點,作為基礎設施層來講,它看上層沒有任何的區別,所以沒有辦法區分業務優先順序。比如說FT的模式,跑CPU指令,它不知道這是最核心支付的指令、還是日誌的指令,再如資料中心之間的同步,儲存層是無法區分交易資料和日誌資料的。

另外網路、虛擬化、儲存等基礎設施,沒有抽象化的概念,複雜度非常高,開發接不了這個工作,必須依賴運維,就要審批。由統一的一幫人來做,而且他們要考證照,比如,網路要有思科的證照,虛擬化要有VMware的證照,要特別專業才能做這件事情,因此會極大地降低迭代速度。業務方無論做什麼事,都要走審批,運維部的人根本忙不過來,這是第二階段的問題。

大規模微服務場景下灰度釋出與流量染色實踐

後來是怎麼改變了這個問題?首先是業務層,業務層接的需求越來越複雜,迭代速度要求越來越快,這個時候單體應用跟不上了,需要進入服務化的架構,工程要拆分,要開始基本的註冊發現,要實現自己的RPC。

大規模微服務場景下灰度釋出與流量染色實踐

應用層的改進會帶來應用層的問題。比如,服務雪崩的問題。大量的請求堆積,一個程式慢了,把整個鏈路也都變慢了,所有人都在等著它緩過來。我們要進行熔斷,快速嘗試另外的服務。原來依賴很多內網負載均衡以及硬體負載均衡的維護代價比較大,一旦出現任何問題,就會引來抖動的問題。所以相應的要有快速恢復、快速熔斷的機制,一旦發現錯誤以後,我們要能夠儘快的重試。

大規模微服務場景下灰度釋出與流量染色實踐

以上就是應用層的問題,經過了一段時間的解決,又引入了新的問題。我把它稱為“雲原生怪圈”,應用向雲原生的(Cloud Native)。它包含兩個層次,第一個層次是應用層的服務數目會增多。第二個層次是資源層申請速度的靈活性會相對增加,這兩個層次形成了一個圈。每家公司可能都存在這個圈,無論是從哪個起點開始,這個圈都可能會被啟用。

一個起點是,很多公司的上面是單體應用,但下面先採購了容器,資源申請靈活性大幅度提高了。一旦靈活性提高了以後,會給應用層釋放很多動力。原來申請一百個機器需要一個星期的審批流程,這時能不拆分就不拆分。而現在有了容器,他會認為我有了這麼好的工具,我可以進行拆分了,反正不費勁,任何一個小部門建立一個小的環境都不費勁。

另外一個起點,先是應用層服務數目增多,給資源層越來越大的壓力,然後會使得你原來七八點下班,現在變成十點多下班,然後十二點下班,壓力越來越大,就會想辦法增加資源層的靈活性。這個圈在整個DevOps的過程中會一直產生的。

微服務化了以後,我們會發現存在以下幾個現象。

第一個是伺服器的機型非常的碎片化,一開始採購機器的時候,有大規格、小規格的,硬碟比例各不一致,導致伺服器非常難以管理,也無法進行批次化的安裝。

第二是很多的程式,不管是虛擬化以後,還是不虛擬化,在不在一臺機器上,QoS無法保證。

第三是測試環境的需求量大大增加,下層的基礎設施根本忙不過來。

大規模微服務場景下灰度釋出與流量染色實踐

接下來進入到雲端計算的平臺。有很多人不理解雲端計算和虛擬化都是運用了虛擬化的技術,兩者之間到底有什麼不同。其實雲端計算帶來了非常大的不同,甚至是本質上的不同。如果你們內部上了一個雲平臺,或者上了公有云,但是你沒有感受到資源申請的靈活性,那肯定是有些姿勢用得不對。

這裡,我總結了一下雲端計算帶來的改變,主要有三大方面,分別是統一介面、抽象概念,租戶自助。正是因為這三大方面,使開發和運維不像原來那樣,有那麼深的隔閡,而是開始逐漸互相靠近,開發部或者業務部開始進行一定的自助。

OpenStack實現介面統一,大部分部署工具支援其介面,可基於開源工具實現釋出的工具化和平臺化

Flavor抽象資源配比(4G 8G 計算最佳化型,網路最佳化型,儲存最佳化型),統一硬體配置,提升利用率,硬體上線效率提升

自動排程代替人工排程,區域可用區抽象對機房機架交換機的感知

雲提供租戶概念,有賬號子賬號體系,有quota,可以讓租戶在管理員許可的範圍內自助操作,加快環境部署速度

VPC遮蔽物理網路複雜性,衝突問題和安全問題,使得租戶可自行配置網路

基於虛擬機器分層映象釋出和回滾機制,構建釋出平臺,可實現大規模批次部署和彈性伸縮

基於虛擬機器的PaaS託管中介軟體,簡化租戶建立,運維,調優中介軟體的難度

釋出平臺提供基於虛擬機器映象+PaaS中介軟體的統一編排

要求業務對於高可用性設計要在應用層完成

大規模微服務場景下灰度釋出與流量染色實踐

在這個階段,要實現微服務框架與開源技術棧的統一。一開始微服務做的比較混亂,有用Spring Cloud,有用Dubbo的,需要一個統一的開源技術棧。另外,還要構建一個持續整合的平臺,透過Agent和虛擬映象部署軟體包。

大規模微服務場景下灰度釋出與流量染色實踐

統一微服務框架之前,我們情況是這樣的,一開始用服務註冊服務發現,還是比較簡單的。後來發現,我們還需要分流、需要降級、配置中心、認證鑑權、監控統計等,在業務程式碼之外加的越來越多,大家的程式碼寫得到處都是,而且依賴於不同人的水平不一樣,有的人寫得好,有的人寫得差,這就是一個當時遇到的問題。

大規模微服務場景下灰度釋出與流量染色實踐

後來我們就把它抽象成為了一個Agent,這個Agent在程式啟動的過程中,透過jar直接帶起來,使得統一的服務框架元件在Agent裡面實現,並且提供統一的介面進行配置,這樣業務方可以只寫業務程式碼,基本上就搞定了這件事。

大規模微服務場景下灰度釋出與流量染色實踐

這樣就形成了一個統一的微服務治理平臺,並且後期會和service mesh做一定的融合。

大規模微服務場景下灰度釋出與流量染色實踐

因此解決了這些問題:

應用減負:使用Agent和Sidecar技術,對應用無成本增強。

開發減負:以微服務治理框架為設計目標、大幅減少重複框架程式碼、避免重複造輪子。

版本控制:統一元件版本配置,避免隱性問題。

相容性:相容的HTTP、RPC呼叫,相容非java應用。

服務治理:根據業務線場景選擇治理支援方法級別治理粒度。

高效能:更低的效能損耗,並提供更細粒度的服務治理。

大規模微服務場景下灰度釋出與流量染色實踐

這時就有了釋出平臺。我們會把包放統一的物件儲存上,透過Agent以映象的方式進行下發。

大規模微服務場景下灰度釋出與流量染色實踐

這是我們的成果,內部都在用這款基於虛擬映象的釋出平臺。

大規模微服務場景下灰度釋出與流量染色實踐

接下來又引入了新的問題,比如難以發現故障點、要引入故障注入服務,API版本混亂,這時需要引入API閘道器。

大規模微服務場景下灰度釋出與流量染色實踐

基於虛擬映象的釋出也很混亂,因為部署的應用越來越多,我們發現虛擬映象的模板越來越多,會出現上千個無法複用的模板,好像每個小組織都有自己的一個東西,畢竟它還不是一個標準,所以接下來我們就擁抱了容器的標準。並且Auto Scaling原來是基於虛擬映象的,現在使用Kubernetes來做,同時實現了分散式事務。

大規模微服務場景下灰度釋出與流量染色實踐

到了這個階段,中間加了Kubernetes這一層。這裡的更新包括,OpenStack可以做物理機的下發,Kubernetes作為統一的對接資源的編排平臺,無論是Vmware上,還是KVM機器上,還是物理機上,公有云上,上面都可以有Kubernetes統一平臺。這個時候只需要對Kubernetes下發一個編排,就可以實現跨多個地方進行部署。

在基於虛擬機器的執行環境和PaaS中介軟體之外,基於Kubernetes也可以有自己的容器映象和執行環境,以及基於容器映象PaaS中介軟體。釋出平臺原來是對接API的,現在有了Kubernetes以後,它可以非常平滑的透過統一的平臺切換到Kubernetes上,所以,做一個釋出平臺,後面的對接還是比較標準的。

應用層也會越來越多,比如說有基於容器映象的彈性伸縮,服務網格,分散式事務,故障注入等。

大規模微服務場景下灰度釋出與流量染色實踐

有了Kubernetes以後,就進入了Dev和Ops的融合階段。這時我們發現,當服務數目再增多的時候,運維的壓力也更大,如果所有的東西都要運維來做,其實是實現不了的。因此,我們建議環境交付提前,比如說一個容器映象裡面的子環境讓開發自己去把控。他知道自己改了哪些內容、哪些配置,不需要透過文件的方式交給運維來做。容器映象還可以做一個很好的事,它是非常好的中介,是一個標準,不論在那兒都可以,所以就產生了左邊的太極圖。運維會幫開發部做一些事情,開發幫運維做一些事情,這個時候進入了開發和運維融合的機制。

大規模微服務場景下灰度釋出與流量染色實踐

因為容器有非常好的分層的機制,如果開發不想寫,可以讓開發寫大部分的基礎環境。

大規模微服務場景下灰度釋出與流量染色實踐

另外一個建議叫不可改變的基礎設施。當規模大了以後,任何一個節點出現了問題,都很難排查,所以我們建議對任何環境的修改,都要在程式碼的級別上修改。在部署平臺之前,程式碼是程式碼,配置是程式碼,單例項執行環境Dockerfile是程式碼,多例項的執行環境編排檔案也是程式碼。

大規模微服務場景下灰度釋出與流量染色實踐

持續交付流水線,是以Master和線上對應的,自己分支開發的模式。按需自動化構建及部署,線上環境還是需要人工觸發的,但基本上是透過流水線程式碼處理的方式來做的。

大規模微服務場景下灰度釋出與流量染色實踐

容器化帶來的另外一個問題,就是“雲原生怪圈”再次起作用。服務規模越來越大,增加速度越來越快,需求指數性增加,大家都需要一個環境。比如一個叢集一千個容器,如果三個小組各開發一個專案,想並行開發,每個人都需要一個環境,一下子需要三千個容器。這時候就需要中介軟體的灰度釋出和流量染色的能力。

大規模微服務場景下灰度釋出與流量染色實踐

大規模微服務場景下灰度釋出與流量染色實踐


在最外層的閘道器上,可以做兩個環境之間流量的分發,以及在微服務的Agent裡面也可以做一個分發。最終,我們會有一個基準環境,就是Master對應的環境。


大規模微服務場景下灰度釋出與流量染色實踐

兩個小組,一組開發了五個服務,另外一組開發了六個服務,他們部署的時候不需要一千個全部布一遍,只需要布五個,布六個。在請求呼叫的時候,從這五個裡面互相調,不在這五個裡面,在基準環境調,另外六個也是。這樣就把三千個變成一千零十幾個,環境大幅度減少。

大規模微服務場景下灰度釋出與流量染色實踐

這個時候環境的合併怎麼辦?環境合併和程式碼合併邏輯一致,統一在釋出平臺管理,誰後合併誰負責Merge。這是我們的一個效果,我們節省了非常多的機器。

大規模微服務場景下灰度釋出與流量染色實踐

有了流量染色功能,就可以做線上的灰度釋出。這裡我們會有幾個環境,一個是預發類的環境,一個是小流量環境,還有一個主流的環境,測試的時候是可以進行染色。

大規模微服務場景下灰度釋出與流量染色實踐

我們以一天的整個開發週期舉例子,每天早上初始化預發環境和小流量環境>>開啟引流,進入持續釋出週期>>程式碼釋出到預發環境進行迴歸,預發環境為單節點部署>>預發透過後釋出到小流量環境,小流量環境三節點部署,滾動釋出>>小流量環境,開發測試及時跟進,觀察異常情況,一旦碰到問題,第一時間關閉流量入口。相關問題定位debug可以在預發環境上進行>>所有釋出到小流量環境的版本合集,透過一個晚高峰的檢測後,釋出到線上環境。第二天同樣是做此迴圈,每天都是這樣的釋出模式。

大規模微服務場景下灰度釋出與流量染色實踐

有了流量染色以後,還可以得到單元化和多機房的染色。如果我們做高可用,至少需要兩個機房,那麼就存在一個問題,當一個機房完全掛了怎麼辦?微服務框架可以把它引流到另外一個機房。服務請求之後,還應該回來,因為應該本機房優先,畢竟本機房的容量大得多。所以我們建議整個部署模式,總分總的部署模式。

首先第一個總,要有統一的釋出平臺,無論釋出到哪個Kubernetes,都應該透過一個平臺。其次,你應該有一個多Kubernetes統一的管理,有多個機房,就有多個Kubernetes,我們並不建議跨機房。然後,我們建議應用層要有統一的檢視,即使Kubernetes出現了問題,應用層可以把流量切到另外一個環境。就是這樣一個總分總的模式。

另外Kubernetes也面臨升級的問題,它更新比較快,經常升級。雖然業界有各種平滑的最佳實踐,但是很難保證它升級的時候不出事。一旦Kubernetes出現狀況,你也不想停裡面的應用,可以採用分流的方式。

大規模微服務場景下灰度釋出與流量染色實踐

最終形成了雲原生架構的技術棧,包括CICD、測試平臺、容器平臺、APM、分散式事務、微服務框架、API閘道器一棧式工具鏈。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69940595/viewspace-2673843/,如需轉載,請註明出處,否則將追究法律責任。

相關文章