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

語言: CN / TW / HK

導語

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

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

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

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

1、微服務概述

2、測試階段最佳實踐

3、發佈階段最佳實踐

4、生產階段最佳實踐

5、微服務架構總結

http://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 化的資源的彈性收縮。