天天看點

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

作者 | 趙奕豪(宿何)  Sentinel 開源項目負責人

來源|

阿裡巴巴雲原生公衆号

前言

微服務的穩定性一直是開發者非常關注的話題。随着業務從單體架構向分布式架構演進以及部署方式的變化,服務之間的依賴關系變得越來越複雜,業務系統也面臨着巨大的高可用挑戰。

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

在生産環境中大家可能遇到過各種不穩定的情況,比如:

  • 大促時瞬間洪峰流量導緻系統超出最大負載,load 飙高,系統崩潰導緻使用者無法下單。
  • “黑馬”熱點商品擊穿緩存,DB 被打垮,擠占正常流量。
  • 調用端被不穩定第三方服務拖垮,線程池被占滿,調用堆積,導緻整個調用鍊路卡死。

這些不穩定的場景可能會導緻嚴重後果,但很多時候我們又容易忽視這些與流量/依賴相關的高可用防護。大家可能想問:如何預防這些不穩定因素帶來的影響?如何針對流量進行高可用的防護?如何保障服務“穩如磐石”?這時候我們就要請出阿裡雙十一同款的高可用防護中間件 —— Sentinel。在今年剛剛過去的天貓 雙11 大促中,Sentinel 完美地保障了阿裡成千上萬服務 雙11 峰值流量的穩定性,同時 Sentinel Go 版本也在近期正式宣布 GA。下面我們來一起了解下 Sentinel Go 的核心場景以及社群在雲原生方面的探索。

Sentinel 介紹

Sentinel

 是阿裡巴巴開源的,面向分布式服務架構的流量控制元件,主要以流量為切入點,從限流、流量整形、熔斷降級、系統自适應保護等多個次元來幫助開發者保障微服務的穩定性。Sentinel 承接了阿裡巴巴近 10 年的 雙11 大促流量的核心場景,例如秒殺、冷啟動、消息削峰填谷、叢集流量控制、實時熔斷下遊不可用服務等,是保障微服務高可用的利器,原生支援 Java/Go/C++ 等多種語言,并且提供 Istio/Envoy 全局流控支援來為 Service Mesh 提供高可用防護的能力。

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

今年年初,Sentinel 社群宣布了 Sentinel Go 版本的釋出,為 Go 語言的微服務和基礎元件提供高可用防護和容錯能力的原生支援,标志着 Sentinel 朝着多元化與雲原生邁出了新的一步。在這半年的時間内,社群推出了近 10 個版本,逐漸對齊了核心高可用防護和容錯能力,同時也在不斷擴充開源生态,與 dubbo-go、螞蟻 MOSN 等開源社群進行共建。

就在近期,

Sentinel Go 1.0 GA 版本

正式釋出,标志着 Go 版本正式進入生産可用階段。Sentinel Go 1.0 版本對齊了 Java 版本核心的高可用防護和容錯能力,包括限流、流量整形、并發控制、熔斷降級、系統自适應保護、熱點防護等特性。同時 Go 版本已覆寫主流開源生态,提供了 Gin、gRPC、go-micro、dubbo-go 等

常用微服務架構的适配

,并提供了 etcd、Nacos、Consul 等

動态資料源擴充支援

。Sentinel Go 也在朝着雲原生的方向不斷演進,1.0 版本中也進行了一些雲原生方面的探索,包括 Kubernetes CRD data-source, Kubernetes HPA 等。對于 Sentinel Go 版本而言,我們期望的流控場景并不局限于微服務應用本身。雲原生基礎元件中 Go 語言生态占比較高,而這些雲原生元件很多時候又缺乏細粒度、自适應的保護與容錯機制,這時候就可以結合元件的一些擴充機制,利用 Sentinel Go 來保護自身的穩定性。

Sentinel 底層通過高性能的滑動視窗進行秒級調用名額統計,結合 token bucket, leaky bucket 和自适應流控算法來透出核心的高可用防護能力。

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

那麼我們如何利用 Sentinel Go 來保證我們微服務的穩定性?下面我們來看幾個典型的應用場景。

高可用防護的核心場景

1. 流量控制與調配

流量是非常随機性的、不可預測的。前一秒可能還風平浪靜,後一秒可能就出現流量洪峰了(例如 雙11 零點的場景)。然而我們系統的容量總是有限的,如果突然而來的流量超過了系統的承受能力,就可能會導緻請求處理不過來,堆積的請求處理緩慢,CPU/Load 飙高,最後導緻系統崩潰。是以,我們需要針對這種突發的流量來進行限制,在盡可能處理請求的同時來保障服務不被打垮,這就是流量控制。流量控制的場景是非常通用的,像脈沖流量類的場景都是适用的。

通常在 Web 入口或服務提供方(Service Provider)的場景下,我們需要保護服務提供方自身不被流量洪峰打垮。這時候通常根據服務提供方的服務能力進行流量控制,或針對特定的服務調用方進行限制。我們可以結合前期壓測評估核心接口的承受能力,配置 QPS 模式的流控規則,當每秒的請求量超過設定的門檻值時,會自動拒絕多餘的請求。

下面是最簡單的一個 Sentinel 限流規則的配置示例:

_, err = flow.LoadRules([]*flow.Rule{
    {
        Resource:          "some-service", // 埋點資源名
        Count:             10, // 門檻值為 10,預設為秒級次元統計,即該請求單機每秒不超過 10 次
        ControlBehavior:   flow.Reject, // 控制效果為直接拒絕,不控制請求之間的時間間隔,不排隊
    },
})           

2. Warm-Up 預熱流控

當系統長期處于低水位的情況下,流量突然增加時,直接把系統拉升到高水位可能瞬間把系統壓垮。比如剛啟動的服務,資料庫連接配接池可能還未初始化,緩存也處于空的狀态,這時候激增的流量非常容易導緻服務崩潰。如果采用傳統的限流模式,不加以平滑/削峰限制,其實也是有被打挂的風險的(比如一瞬間并發很高)。針對這種場景,我們就可以利用 Sentinel 的 Warm-Up 流控模式,控制通過的流量緩慢增加,在一定時間内逐漸增加到門檻值上限,而不是在一瞬間全部放行,同時結合請求間隔控制+排隊的控制效果 來防止大量請求都在同一時刻被處理。這樣可以給冷系統一個預熱的時間,避免冷系統被壓垮。

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

3. 并發控制與熔斷降級

一個服務常常會調用别的子產品,可能是另外的一個遠端服務、資料庫,或者第三方 API 等。例如,支付的時候,可能需要遠端調用銀聯提供的 API;查詢某個商品的價格,可能需要進行資料庫查詢。然而,這個被依賴服務的穩定性是不能保證的。如果依賴的服務出現了不穩定的情況,請求的響應時間變長,那麼調用服務的方法的響應時間也會變長,線程會産生堆積,最終可能耗盡業務自身的線程池,服務本身也變得不可用。

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

現代微服務架構都是分布式的,由非常多的服務組成。不同服務之間互相調用,組成複雜的調用鍊路。以上的問題在鍊路調用中會産生放大的效果。複雜鍊路上的某一環不穩定,就可能會層層級聯,最終導緻整個鍊路都不可用。Sentinel Go 提供以下的能力避免慢調用等不穩定因素造成不可用:

  • 并發控制(isolation 子產品):作為一種輕量級隔離的手段,控制某些調用的并發數(即正在進行的數目),防止過多的慢調用擠占正常的調用。
  • 熔斷降級(circuitbreaker 子產品):對不穩定的弱依賴調用進行自動熔斷降級,暫時切斷不穩定調用,避免局部不穩定因素導緻整體的雪崩。

Sentinel Go 熔斷降級特性基于熔斷器模式的思想,在服務出現不穩定因素(如響應時間變長,錯誤率上升)的時候暫時切斷服務的調用,等待一段時間再進行嘗試。一方面防止給不穩定服務“雪上加霜”,另一方面保護服務的調用方不被拖垮。Sentinel 支援兩種熔斷政策:基于響應時間(慢調用比例)和基于錯誤(錯誤比例/錯誤數),可以有效地針對各種不穩定的場景進行防護。

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

注意熔斷器模式一般适用于弱依賴調用,即降級後不影響業務主流程,開發者需要設計好降級後的 fallback 邏輯和傳回值。另外需要注意的是,即使服務調用方引入了熔斷降級機制,我們還是需要在 HTTP 或 RPC 用戶端配置請求逾時時間,來做一個兜底的防護。

4. 熱點防護

流量是随機的,不可預測的。為了防止被大流量打垮,我們通常會對核心接口配置限流規則,但有的場景下配置普通的流控規則是不夠的。我們來看這樣一種場景——大促峰值的時候,總是會有不少“熱點”商品,這些熱點商品的瞬時通路量非常高。一般情況下,我們可以事先預測一波熱點商品,并對這些商品資訊進行緩存“預熱”,以便在出現大量通路時可以快速傳回而不會都打到 DB 上。但每次大促都會湧現出一些“黑馬”商品,這些“黑馬”商品是我們無法事先預測的,沒有被預熱。當這些“黑馬”商品通路量激增時,大量的請求會擊穿緩存,直接打到 DB 層,導緻 DB 通路緩慢,擠占正常商品請求的資源池,最後可能會導緻系統挂掉。這時候,利用 Sentinel 的

熱點參數流量控制

,自動識别熱點參數并控制每個熱點值的通路 QPS 或并發量,可以有效地防止過“熱”的參數通路擠占正常的調用資源。

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

再比如有的場景下我們希望限制每個使用者調用某個 API 的頻率,将 API 名稱+userId 作為埋點資源名顯然是不合适的。這時候我們可以在給 API 埋點的時候通過 

WithArgs(xxx)

 将 userId 作為參數傳入到 API 埋點中,然後配置熱點規則即可針對每個使用者分别限制調用頻率;同時,Sentinel 也支援針對某些具體值單獨配置限流值,進行精細化流控。像其他規則一樣,熱點流控規則同樣支援通過動态資料源進行動态配置。

Sentinel Go 提供的 RPC 架構整合子產品(如 Dubbo、gRPC)均會自動将 RPC 調用的參數清單附帶在埋點中,使用者可以直接針對相應的參數位置配置熱點流控規則。注意如果需要配置具體值限流,受類型系統限制,目前僅支援基本類型和 string 類型。

Sentinel Go 的熱點流量控制基于緩存淘汰機制+令牌桶機制實作。Sentinel 通過淘汰機制(如 LRU、LFU、ARC 政策等)來識别熱點參數,通過令牌桶機制來控制每個熱點參數的通路量。目前的 Sentinel Go 版本采用 LRU 政策統計熱點參數,社群也已有貢獻者送出了優化淘汰機制的 PR,在後續的版本中社群會引入更多的緩存淘汰機制來适配不同的場景。

5. 系統自适應保護

有了以上的流量防護場景,是不是就萬事無憂了呢?其實不是的,很多時候我們無法事先就準确評估某個接口的準确容量,甚至無法預知核心接口的流量特征(如是否有脈沖情況),這時候靠事先配置的規則可能無法有效地保護目前服務節點;一些情況下我們可能突然發現機器的 Load 和 CPU usage 等開始飚高,但卻沒有辦法很快的确認到是什麼原因造成的,也來不及處理異常。這個時候我們其實需要做的是快速止損,先通過一些自動化的兜底防護手段,将瀕臨崩潰的微服務“拉”回來。針對這些情況,Sentinel Go 提供了一種系統自适應保護規則,結合系統名額和服務容量,自适應動态調整流量。

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

Sentinel 系統自适應保護政策借鑒了 TCP BBR 算法的思想,結合系統的 Load、CPU 使用率以及服務的入口 QPS、響應時間和并發量等幾個次元的監控名額,通過自适應的流控政策,讓系統的入口流量和系統的負載達到一個平衡,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。系統規則可以作為整個服務的一個兜底防護政策,保障服務不挂,對 CPU 密集型的場景會有比較好的效果。同時,社群也在結合自動化控制理論和強化學習等手段,持續完善自适應流控的效果和适用場景。在未來的版本中,社群會也推出更多試驗性的自适應流控政策,來滿足更多的可用性場景。

雲原生探索

雲原生是 Sentinel Go 版本演進最為重要的一環。在 GA 的過程中,Sentinel Go 社群也在 Kubernetes 和 Service Mesh 等場景下進行了一些探索。

1. Kubernetes CRD data-source

在生産環境中我們一般都需要通過配置中心來動态管理各種規則配置。在 Kubernetes 叢集中,我們可以天然利用 Kubernetes CRD 的方式來管理應用的 Sentinel 規則。在 Go 1.0.0 版本中社群提供了基本的 Sentinel 規則 CRD 抽象以及相應的

資料源實作

。使用者隻需要先導入 Sentinel 規則 CRD 定義檔案,接入 Sentinel 時注冊對應的 data-source,然後按照 CRD 定義的格式編寫 YAML 配置并 kubectl apply 到對應的 namespace 下即可實作動态配置規則。以下是一個流控規則的示例:

apiVersion: datasource.sentinel.io/v1alpha1
kind: FlowRules
metadata:
  name: foo-sentinel-flow-rules
spec:
  rules:
    - resource: simple-resource
      threshold: 500
    - resource: something-to-smooth
      threshold: 100
      controlBehavior: Throttling
      maxQueueingTimeMs: 500
    - resource: something-to-warmup
      threshold: 200
      tokenCalculateStrategy: WarmUp
      controlBehavior: Reject
      warmUpPeriodSec: 30
      warmUpColdFactor: 3           

Kubernetes CRD data-source 子產品位址:

https://github.com/sentinel-group/sentinel-go-datasource-k8s-crd

後續社群會進一步完善 Rule CRD 定義并與其它社群一起探讨高可用防護相關的标準抽象。

2. Service Mesh

Service Mesh 是微服務向雲原生演進的趨勢之一。在 Service Mesh 架構下,一些服務治理和政策控制的能力都逐漸下沉到了 data plane 層。去年 Sentinel 社群在 Java 1.7.0 版本裡面做了一些嘗試,提供了 Envoy Global Rate Limiting gRPC Service 的實作 ——

Sentinel RLS token server

,借助 Sentinel 叢集限流 token server 來為 Envoy 服務網格提供叢集流量控制的能力。今年随着 Sentinel Go 版本的誕生,社群與更多的 Service Mesh 産品開展合作、整合。我們與螞蟻的 MOSN 社群進行共建,在 MOSN Mesh 中原生支援了 Sentinel Go 的流控降級能力,同時也已在螞蟻内部落地。社群也在探索更為通用的方案,如利用 Istio 的 Envoy WASM 擴充機制實作 Sentinel 插件,讓 Istio/Envoy 服務網格可以借助 Sentinel 原生的流控降級與自适應保護的能力來保障整個叢集服務的穩定性。

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

3. Kubernetes HPA based on Sentinel metrics

保障服務穩定性的方法多種多樣,除了各種規則對流量進行“控制”之外,“彈性”也是一種思路。對于部署在 Kubernetes 中的應用來說,可以利用 Kubernetes HPA 能力進行對服務進行水準擴縮容。HPA 預設支援多種系統名額,并且支援自定義名額統計。目前我們已經在阿裡雲 Kubernetes 容器服務上結合

AHAS Sentinel

支援基于服務的平均 QPS、響應時間等作為條件進行彈性伸縮。社群也正在這一塊做一些嘗試,将一些 Sentinel 的服務級别的名額統計(通過量,拒絕量,響應時間等)通過 Prometheus 或 OpenTelemetry 等标準方式透出,并适配到 Kubernetes HPA 中。

阿裡 雙11 同款流控降級元件 Sentinel Go 正式 GA,助力雲原生服務穩穩穩前言Sentinel 介紹高可用防護的核心場景雲原生探索Let's start hacking!

當然基于 Sentinel 的彈性方案不是萬靈藥,它隻适用于一些特定的場景,比如适用于啟動速度快的無狀态服務(Serverless 場景)。對于啟動較慢的服務,或非本服務容量問題的場景(如依賴的 DB 容量不夠),彈性的方案不能很好地解決穩定性的問題,甚至可能會加劇服務的惡化。

Let's start hacking!

了解了以上的高可用防護的場景,以及 Sentinel 在雲原生方向的一些探索,相信大家對微服務容錯與穩定性的手段有了新的體會。歡迎大家動手玩一下 demo,将微服務接入 Sentinel 來享受高可用防護和容錯的能力,讓服務“穩如磐石”。同時 Sentinel Go 1.0 GA 版本的釋出離不開社群的貢獻,感謝所有參與貢獻的小夥伴們。

本次 GA 我們也新加入了兩位給力的 committer —— @sanxun0325 和 @luckyxiaoqiang,兩位在 1.0 版本的演進帶來了 Warm Up 流控、Nacos 動态資料源以及一系列功能改進和性能優化,非常積極地幫助社群答疑解惑以及 review 代碼。恭喜兩位!社群在未來版本中也會朝着雲原生和自适應智能化的方向不斷探索和演進,也歡迎更多的同學加入貢獻小組,一起參與 Sentinel 未來的演進,創造無限可能。我們鼓勵任何形式的貢獻,包括但不限于:

  • bug fix
  • new features/improvements
  • dashboard
  • document/website
  • test cases

開發者可以在 GitHub 上面的 good first issue 清單上挑選感興趣的 issue 來參與讨論和貢獻。我們會重點關注積極參與貢獻的開發者,核心貢獻者會提名為 Committer,一起主導社群的發展。我們也歡迎大家有任何問題和建議,都可以通過 GitHub issue、Gitter 或釘釘群(群号:30150716)等管道進行交流。Now start hacking!

繼續閱讀