從三萬英尺看全鏈路灰度

阿里云云原生發表於2022-12-26

作者:卜比

全鏈路灰度是微服務領域,很實用的企業級場景下的技術能力。

從本期開始,我們將透過《全鏈路灰度:自頂向下的方法》的系列文章,由遠及近的剖析全鏈路灰度全貌,系列文章分為 4 篇:

《從三萬英尺看全鏈路灰度》:介紹微服務的基礎概念、主流的部署模式。

《從三千英尺看全鏈路灰度》:介紹全鏈路灰度和涉及的元件,以及如何組裝成全鏈路灰度的能力。

《從三百英尺看全鏈路灰度》:從技術細節入手,分享如何實現路由能力和灰度能力。

《總結篇》:總結全鏈路灰度,目的是更加高效支援好業務同學,進一步保證線上穩定性。

微服務架構的優勢

劃分微服務層次結構,拆分複雜度

在微服務架構出現之前,更多的業務採用的是單體架構。單體架構在複雜業務場景下,每一個開發人員都無法準確的評估複雜度:每一個修改都需要遍歷程式碼庫,確定這個修改不會影響其他功能。

在微服務架構出現後,透過 RPC、訊息佇列等技術,我們可以很好的劃分出微服務體系結構(microservices hierarchy):架構師關注業務邏輯;業務開發者關注微服務內的業務自洽;中介軟體開發者關注基礎設施的高效和穩定。分離、拆分了複雜度。

高內聚低耦合,讓業務更加聚焦

在單體架構中,程式碼的模組化一般是透過 package、namespace 等語言特性來實現的,但這種模組化的實現,會有各種各樣的問題:

  • package、namespace 等特性是語言相關的,如果出現跨語言的情況,需要重新組織程式碼結構
  • 模組化劃分沒有標準。以 Java 為例,是以 controller、service 等元件型別來劃分 package?還是以各個業務域來劃分 package?
  • package 劃分缺少強制工具。即使我們定了劃分標準,但 package 仍不能強制限定模組化,業務同學寫出了跨模組的呼叫,仍然能透過測試、上線。

面對上述問題,亞馬遜提出了 API-first、FaceBook 開源了 Thrift、Google 開源了 gRPC,幫助開源社群構建了微服務基礎設施。

限制不好的架構設計,讓程式碼能夠無負擔進化

在單體架構時代,經常遇到一些比較難看的設計,但是改動這些程式碼,總是會遇到相容性問題,不能徹底移除。

拆分成微服務後,每個微服務都可以有自己的開發語言、設計模式,即使出現了設計問題,我們也能夠將這些糟糕的設計限定在每個服務內部,阻止了架構的腐化和失控。

微服務的基礎概念

 title=

微服務生態圖

上面這張圖很好的展示了微服務體系下,我們需要依賴的基礎設施以及相關開源專案,下面我們分模組簡要介紹下:

  • 微服務之間要能夠互相發現、互相呼叫,就需要註冊中心。
  • 微服務的部署需要標準化,方便遷移、擴縮容,業界比較流行的部署模式有 Kubernetes。
  • 微服務的問題排查、監控等,需要可觀測元件。
  • 微服務體系需要引入外部流量、鑑權等,需要微服務閘道器。
  • 微服務的資料儲存,根據存取的方式、成本不同,可以使用 MySQL 或者 Redis 等。
  • 需要實現全鏈路灰度、API 管理等微服務治理功能,就需要治理中心。

微服務的拆分

技術層面上,微服務的拆分,通常可以按照業務模組、業務場景等進行拆分,儘量確保服務邏輯自洽、對外其他比較少,做到高內聚低耦合。緊密關聯的業務邏輯,放在一個微服務內,避免在服務與服務之間共享資料。

從組織結構層面上,微服務解決的根本問題是團隊分工問題,詳見康威定律,這是大型軟體發展的必然,不因為人的喜好而改變。當你讀懂康威定律,就會發現“服務拆分粒度難以準確把握”根本不是本質問題。

你有幾個 2 pizza 團隊,最好就拆成幾個微服務。舉一個現實的例子:只有一個開發人員時,儘量就做單體應用,不要沒事找刺激拆成 10 個微服務,最終這個開發人員還會把他合成一個。微服務要求縱向的 2 pizza 團隊(無數個小團隊,包含開發、測試、運維),當然我們也實施過一些傳統大型企業,但團隊還是處在橫向結構的場景下(開發、運維、測試各是一個團隊),拆分微服務讓他們很痛苦,尤其是運維團隊。

 title=

微服務的部署

從大體上來看,微服務至少需要部署線上上和測試環境。但需要注意的是,開發口中的環境和此處的環境會很容易混淆,所以我們借用 K8s 名稱空間的概念,使用名稱空間來防止混淆。

線上上名稱空間中,我們能夠保證程式碼都是經過 review 的、資料庫都是線上資料。線上的應用版本,一般分為 prod(生產版本)、gray(灰度版本,少部分線上流量進入)、pre(預發版本,僅內部人員可用)。

在測試名稱空間中,測試同學和開發同學發起流量進行測試和開發。在測試環境中,一般每個應用都部署了 stable 版本,提供一個穩定的測試環境;根據專案、開發流程的不同,相關的應用也會部署一些 project1 版本等。

另外,對於註冊中心、Kubernetes 叢集、訊息佇列等基礎元件,也應當在不同的部署環境中單獨部署一套。比如線上名稱空間中的註冊中心,和測試名稱空間中的註冊中心,應當分開部署,做到硬性隔離。

微服務流量灰度路由

對於不同的名稱空間,不同的部署版本,我們都要考慮到流量是怎麼路由的,不合理的流量輕則困擾研發、測試進度,重則導致線上事故。

線上流量

對於大部分使用者和流量,都應該路由到 prod 版本上。

對於符合灰度要求(比如百分比規則、特定使用者等),應該路由到 gray 版本上。

對於內部驗證賬號,應該路由到 pre 版本上,驗證功能是否正常。

測試環境流量

對於屬於專案環境中的流量,自然應該路由到對應的專案環境中。

對於不屬於任何專案環境中的流量,我們將其路由到 stable 版本中。

總結

下面這張圖能夠反映出恰當的生產、測試部署環境下,整體微服務的部署、流量走向、環境隔離:

 title=

至此,我們對微服務全鏈路灰度有了一個全域性(且粗糙)的認知,我們當然需要了解全鏈路灰度是如何實現的,如何讓流量根據不同的特徵,路由到不同的節點。這些內容就是下一篇文章要講的 《全鏈路灰度原理——從三千英尺看全鏈路灰度》 ,敬請期待!

點選此處,前往微服務引擎官網檢視更多詳情~

相關文章