微服務架構下路由、多活、灰度、限流的探索與挑戰

語言: CN / TW / HK

導語

2022騰訊全球數字生態大會已圓滿落幕,大會以“數實創新、產業共進”為主題,聚焦數實融合,探索以全真互聯的數字技術助力實體經濟高質量發展。大會設有29個產品技術主題專場、18個行業主題專場和6個生態主題專場,各業務負責人與客戶、合作伙伴共同總結經驗、凝結共識,推動數實融合新發展。

今年6月,騰訊宣佈內部海量自研業務實現全面上雲,成為國內最大規模的雲原生實踐,累計節省IT成本超過30億元,充分顯示騰訊雲的產品、技術和綜合服務能力。

雲原生技術在雲端計算 PaaS 的應用已經邁入深水區,騰訊雲微服務和中介軟體產品基於客戶業務落地實踐,在產品能力、可用性和可運維性等多個方面進行了深入的優化和落地。本次大會設立了微服務與中介軟體專場,本專場從產品研發、運維等最佳落地實踐出發,詳細闡述雲原生時代,企業在開發微服務和構建雲原生中介軟體過程中應該怎樣少走彎路,聚焦業務需求,助力企業發展創新。本篇為微服務與中介軟體專場第一個演講議題的乾貨集錦,歡迎大家收看!

本文將從以下五個方面展開,對微服務架構下路由、多活、灰度、限流的探索與挑戰進行深入解析。

1、微服務概述

2、測試階段最佳實踐

3、釋出階段最佳實踐

4、生產階段最佳實踐

5、微服務架構總結

https://www.bilibili.com/video/BV1iM411B7M7/?spm_id_from=333.999.0.0&vd_source=479307cf5f3abfaabd9d90eb33158e29

微服務概述

企業架構演進之路

應用層

最早的應用架構,也就是IT系統通常都是一個單體架構,隨著技術的發展與進步,出現了 SOV 這種面向服務的架構,一直髮展到現如今,最流行的架構就是微服務架構。

單體架構:

  • 緊耦合,系統複雜,牽一髮而動全身
  • 重複製造各種輪子
  • 完全封閉的架構

SOA架構包括介面層、邏輯層和資料層:

  • 通常通過 ESB 進行系統整合,鬆耦合
  • 需要集中式、計劃內停機擴容或更新
  • 團隊龐大,溝通成本高

微服務架構:

  • DevOps: CI/CD, 全自動化
  • 可擴充套件性:自動彈性伸縮
  • 高可用:升級、擴容不中斷業務

資源層

隨著應用層的發展,資源層的發展也隨之改變,對應單體架構的時候,大家都還是 IDC 基礎設施,這是第一階段;到了第二階段,大家開始慢慢上雲,就有了雲端計算與虛擬化技術;到了第三階段,大家開始探索怎麼去做容器化;隨之到了第四階段也就是現在,大家又開始探索怎麼去做 Severless 無伺服器的這種方式。

企業架構演進下的挑戰

到了微服務架構之後,大家又想要去實現更多的場景,比如 Devops、架構的可擴充套件性、架構的高可用以及多環境路由、釋出等,接踵而至的就是層出不窮的挑戰。

如何做流量路由?

如何保證多活容災?

如何實現金絲雀、藍綠髮布?

如何實現全鏈路灰度?

如何扛住流量洪峰?

接下來,我們就探討一下在以上挑戰之下的微服務實踐。

測試階段微服務的實踐

測試階段:解決多測試環境的流量路由問題

痛點

微服務系統中,在開發測試時,如果有多團隊同時開發,或者多系統需要聯調,每次都需要部署全量服務來進行測試。如何做到僅部署本次有變更的服務,其他服務通過流量動態路由的方式複用基線環境服務資源,成為這種微服務測試階段的一大痛點。

目標

1、節約資源成本,開發/測試按需申請,用完即棄;

2、提升研發效率,擺脫大量的本地化配置的工作;

3、實現跨環境的聯調,不用爭搶不同的測試環境。

為了實現這個方案,需要用到微服架構裡面的兩個元件,一個是入口層的閘道器,另一個是服務治理框架例如服務網格等。

如何實現呢?

如下圖所示,在測試環境裡面通常會有多個環境,分為基線環境和特性環境,在測試的過程中,團隊1想要去測左邊藍色的特性環境,團隊2想要去測右邊綠色的特性環境,這個時候就可以通過服務治理的框架來實現。

實現方案

1、例項打標

K8s註冊場景:在workload上通過新增annotation打上環境標籤。

微服務框架註冊場景:對服務下所有例項進⾏分組,通過標籤能夠區分部署的環境。

2、流量染色

入口閘道器對流量特性進⾏染色。例如:給特定uin的請求進行染色。

3、閘道器到後端服務的流量路由

入口閘道器通過標籤路由,按照請求中的測試環境資訊進行動態路由。

4、後端服務與服務間的路由

 治理中心根據請求流量特徵對不同測試環境中的服務進⾏動態路由。

釋出階段的微服務實踐

釋出階段:實現金絲雀、滾動或者藍綠髮布

微服務架構下,會涉及到釋出的問題。

目前有三種流行的釋出方式,一種是金絲雀釋出,一種是滾動釋出,一種是藍綠髮布,這三種常見的釋出策略原理都是一樣,都是期望在釋出的過程中,把要釋出的新的版本都做到絕對的測試,讓所有的使用者用的過程中,避免新版本有任何問題影響到所有的使用者。但是在釋出的過程中,這三種釋出方式的策略會有一些不一樣。

  • 金絲雀釋出

金絲雀釋出就是對於本次的釋出,按比例去升級,一定的例項,沒有問題的話,再逐步的放開這個比例,直到最終所有的流量都到了V2版本,這就實現了一個金絲雀。

  • 滾動釋出

對於本次釋出的服務,先升級一個/批例項,測試沒問題了,再分批升級剩餘例項,直到所有例項都升級到V2版本。

  • 藍綠髮布

藍綠髮布是把例項分為兩個陣營,一個綠陣營和一個藍陣營,正在執行的例項是V一版本,把它放到綠陣營,這個時候部署了新的例項V2版本到藍陣營裡面。然後對V2版本進行全面的測試,測試沒問題了之後再通過負載均衡,把流量從V1切到V2,這樣就實現了一個無縫的釋出,同時保證新版本線上環境的全面測試.

如何實現指定流量比例進行灰度釋出

如下圖所示,利用 API 閘道器和註冊配置中心來實現指定流量比例進行灰度釋出。在入口層,用 API 閘道器訪問服務A,然後對服務A升級了一個V2版本,通過 API 閘道器調節10%的流量,從V1切到V2版本,這就實現了入口層的按流量比例的灰度。V2版本測試沒問題後,再把百分百的流量切到V2版本來。

那在服務間呼叫的時候是怎麼做呢?可以看到下圖的下半部分,用服務B去呼叫服務C,這個過程中,對服務C進行升級,升級到V2版本,那麼服務C裡面就會有一個V2的例項,然後通過註冊配置中心調節10%的流量,從服務B去呼叫服務C,就實現了服務間呼叫的按流量比例的灰度。

實現方案

1、閘道器調節比例

將一定比例的流量導向到V2版本。

2、註冊配置中心調節比例

將一定比例的流量導向到V2版本。

如何實現指定部分使用者、地域或者其他條件進行灰度

如右下圖所示,在入口層服務A釋出了V2版本,然後通過閘道器對想要進行灰度的條件進行設定,那麼閘道器就可以根據設定的條件,比如 Header 裡面帶有某個引數,或者是 Pass 裡面帶有某個引數,根據這樣的設定條件,特定的使用者就可以訪問到V2版本,實現入口層的流量切換。

在服務間呼叫的時候,如果想要實現條件灰度,就需要用到服務治理的框架,比如服務網格里帶的標籤路由,可以對服務C進行打標,然後再去做流量路由的時候,按照這個條件路由到V2版本的服務C裡面,這樣就實現服務網格的流量路由了。

實現方案

1、閘道器調節比例

將一定比例的流量導向到V2版本。

2、服務網格設定條件路由

按條件將流量導向到V2版本。

釋出階段:實現全鏈路灰度

全鏈路灰度是什麼意思呢?就是在釋出正式版本之前,有一個灰度環境能夠去測試所有功能,端到端的測試,為了保證功能釋出上線之後,不會影響其他的客戶,先在小範圍內進行測試,沒問題了再全量釋出。

如下圖所示,首先對環境進行區分,比如說在生產環境裡面,有一個正式環境,有一個灰度環境,當要釋出一個新功能的時候,就把對應的新功能的例項部署到灰度環境裡面去;然後通過服務治理框架對這個例項進行打標,加上標籤,區分它是灰度環境的例項;接著在閘道器層路由這個流量的時候,對流量進行灰度染色,通常會有動態染色或者靜態染色兩種方式,但不管哪種方式,目的都是為了把流量做出區分。普通流量全部進入正式環境,對於想要灰度的流量就標記為V2,就可以從V2版本進入到灰度環境裡面,在灰度環境裡,使用者中心到積分中心的時候會回到正式環境,因為積分中心沒有灰度環境的例項,這時就需要用到服務治理框架,對流量進行路由,同樣的正式環境訪問灰度環境,也是通過這樣的路由線路實現的。

優勢

  • 全鏈路隔離流量泳道​
  • 端到端的穩定環境​
  • 流量一鍵切流​
  • 可觀測能力

實現方案

1、例項打標

K8s 註冊場景:在 Workload 上通過新增 Pod lables 打上版本標籤。

微服務框架註冊場景:對服務下的所有例項進⾏分組,通過標籤能夠區分版本。

2、流量染色

閘道器對流量特性進⾏灰度染色。有動態染色與靜態染色兩種方式。

3、閘道器到後端服務的流量路由

通過標籤路由,按照請求中的服務版本資訊進行流量轉發。

4、後端服務與服務間的路由

在鏈路上各服務能夠根據請求流量特徵進⾏動態路由。

生產階段的微服務實踐

生產階段:實現多活容災

同城多活

多活容災是一個雲原生的多活容災架構解決⽅案。

眾所周知,同一個地域通常會有多個可用區。如下圖所示,有可用區1和可用區2,在兩個可用區部署同一個服務A,然後服務A會讀寫底層的資料庫,而資料庫會有主備之分,主資料庫在可用區1,備用資料庫在可用區2。那麼這時,在閘道器層就可以對流量按比例進行分發,可以進入可用區1也可以進入可用區2,可用區1的服務A可以對主資料庫進行讀寫操作,而可用區2的服務對主資料庫只會進行寫操作,它的讀操作會從備份資料庫來。同時主資料庫會實時的把資料同步到備份資料庫裡面,這樣就做到了同城多活容災的架構場景。

在微服務中,通常一個應用的多個節點會部署在不同的可用區,然後註冊到同一個服務下,這樣就實現註冊中心的多活。

生產階段:微服務架構的多活容災

在微服務架構下的多活容災,除了服務例項本身以外,還會涉及到閘道器、註冊配置中心等相關元件。

如下圖所示,入口層閘道器通常都要跨可用區部署,紅色的線隔離的是不同的可用區,假如有一區、二區、三區,在這個過程中,閘道器就可以變成3個節點部署到三個區。註冊配置中心也是一樣的,分三個節點來部署到3個可用區,然後對應的服務就可以自動的部署到3個可用區,這樣做的好處在於,如果任何一個可用區掛掉,服務還能夠正常的響應,來保證整個架構的高可用。

生產階段:接入層多活容災

在生產階段,如何去做接入層的多活容災呢?

如果想要在接入層實現多活,通常需要做到幾個事情:

  • 流量比例切換
  • 同城容災切換
  • 跨城容災切換

這就需要用到一個功能比較強大的閘道器,比如現在流行的 Kong 閘道器或者是 Nginx,來實現類似的操作。所有的閘道器應該都支援流量比例切換,只需要調節不同的流量比例到不同的可用區就可以了,如下圖所示,廣州一區的服務掛了,可以從閘道器手動的切換流量比例到廣州二區,也可以實現自動的切換。要做到同城的容災切換,只要把流量切到廣州二區來響應同城的容災。假如整個廣州區都掛掉了,還可以從閘道器層直接把所有的流量全部切換到上海二區來實現這種跨城的容災。

生產階段:實現多活容災和就近訪問

如何在這個服務間實現多活容災和就近訪問?

就近訪問是什麼意思呢?

比如現在有一個服務有兩個例項,同時在廣州部署了一個例項,也在上海部署了一個例項,有個上海的使用者想要訪問這個服務,如果他訪問到的是廣州的例項,整個訪問的鏈路就會變得更長,延時也會增加,所以就近訪問到上海的例項是最好的。

就近訪問怎麼做呢?

通過服務治理框架配置服務的地域資訊,比如兩個例項,第一個例項配置在廣州地域,第二個例項在上海地域,當用戶在訪問的時候,服務框架就可以識別上海的使用者應該到上海地域,來實現就近訪問。

服務間的多活容災區怎麼做呢?

其實原理和接入層是差不多的,如下圖所示,有一個廣州一區的積分中心,想要去訪問活動中心,但這個時候活動中心掛掉了,那通常服務治理框架就會去主動探活,發現活動中心掛了,它就會主動的去做同城的容災切換,把積分中心切換到廣州二區的活動中心來訪問,這樣就做到同城的容災。如果廣州區全部掛掉了,那麼服務治理框架就可以把服務的流量自動切換到上海區來實現跨城容災,黎明覺醒這個遊戲就是通過這樣的方式來實現跨城容災架構的。

生產階段:支援單元化架構的路由

痛點:

  • 資源無法滿足橫向擴充套件需求;
  • 業務需要支援 SET 程式碼改造;
  • 業務的訪問使用者在地理位置上分佈較廣,希望解決地理位置問題。

單元化方案:

  • 業務系統部署在多地域的不同資料中心中。
  • 通過SET化實現不同區域的流量在本區域內閉環操作。
  • 某SET出現故障後業務流量切換至其他SET。

實現方案:

1、例項打標:對服務下的所有例項按照單元(SET)進⾏分組,通過標籤能夠區分單元(SET)。

2、動態路由:根據請求流量特徵對不同單元模組(SET)中的服務進⾏動態路由。

3、隔離:SET 間服務呼叫的強隔離。

具體怎麼操作呢?

在服務治理的框架裡面對不同的例項進行分組,如下圖所示,有個使用者中心有6個例項,把左邊的3個例項歸為單元1,右邊的3個例項標記為單元2,這樣就實現了按例項的分組,對應的所有訪問的服務都把它歸到單元1裡面,這樣做的好處就是在整個訪問的過程中,可以保證流量都在這個單元內,這就實現單元與單元之間的隔離操作。這樣的過程主要依賴於註冊配置中心以及服務治理框架,來對例項進行打標,進行分組,來實現的單元化。微信支付就是通過單元化的架構來實現對金融級的安全可靠的交易系統架構的保障。

生產階段:限流場景

限流階段:

1.接入層流量限流

2.服務間呼叫限流

限流維度:

1.服務/介面/標籤的限流

2.秒、分鐘、小時、天等時間微服的限流

限流型別:

1.單機限流:針對單個被調例項的級別的限流,流量限額只針對當前被調例項生效,不共享。

2.分散式限流:針對服務下所有例項級別的限流,多個服務例項共享同一個全域性流量限額

下圖是一個簡單的架構圖關於如何在入口層以及服務間做限流。

不同的限流會在不同的階段去做。如下圖所示,在入口層的限流通常是由閘道器來做,配置一定的限流規則後,當大量的流量請求進來,觸發了限流規則,通常會做丟棄或者排隊兩件事,針對攻擊的場景,通常會把這無效的請求全部丟棄;針對正常的訪問,比如搶購、秒殺等場景,就會對它進行排隊,去訪問後端的服務,來保證後端的服務不被擊穿。在服務間呼叫的時候,比如使用者中心去呼叫積分中心,當流量變大的時候觸發了積分中心的限流規則,積分中心就會根據服務治理框架配置的限流規則去進行丟棄或者排隊,通常在服務間的呼叫都會進行勻速排隊來做到限流的作用。

王者榮耀以及騰訊視訊每年會做大量的營銷活動,做活動的時候流量就會突增,這樣的流量突增,為了保護後端服務不被擊穿,資料庫不被擊穿,一定會在入口層服務間做限流規則,他們就是利用閘道器以及服務治理的框架來實現的這種限流的場景。

微服務架構總結

典型的微服務架構

請求從前端進來之後會進到閘道器,騰訊雲主要使用的是雲原生閘道器,它具有 CLB 負載均衡能力、安全路由能力以及限流能力,可以把請求轉發到後端的服務,後端的服務主要是指騰訊雲微服務,每個服務都會有多個彈性例項來響應不同的業務的波峰波谷,它會自動彈性伸縮來支撐高流量時資源不足的情況,同時也會在低流量的時候不造成資源浪費的情況。這麼多服務的管理一定會有註冊中心來保證服務的註冊與發現,以及配置中心來管理所有服務的配置,再配合服務治理中心來實現動態路由熔斷限流等,還包括底層的鏈路追蹤和監控來實現完整的微服務架構。

那麼要實現一個典型的微服務架構,騰訊雲這邊是用什麼樣的產品來支撐呢?那就是微服務引擎 TSE。

微服務引擎 TSE 提供開源增強的雲原生閘道器、註冊配置中心、服務治理平臺和彈性微服務,幫助使用者快速構建輕量、高可用和易伸縮的微服務架構。微服務引擎的使用方式完全相容開源版本,在功能、可用性和可運維性等多個方面進行增強。

  • 雲原生閘道器主要分為Kong和 Nginx 開源的元件來支撐閘道器的一些訴求。
  • 註冊配置中心支援市面上主流的元件 Rookie Parlacos、阿波羅、Console、URA卡。
  • 服務治理中心,是騰訊開源自研的北極星,北極星在騰訊內部的影響力非常大,微信支付、王者榮耀都在使用北極星來作為它的服務治理的框架去實現上面所講到的限流、全鏈路灰度以及多活容災等場景。
  • 彈性微服務負責實現服務本身的部署和執行來達到 Serverless 化的資源的彈性收縮。