数据库降级_阿里 双11 同款流控降级组件 Sentinel Go 正式GA,云原生服务稳稳稳...
作者 | 趙奕豪(宿何) Sentinel 開源項(xiàng)目負(fù)責(zé)人來源|阿里巴巴云原生公眾號
前言
微服務(wù)的穩(wěn)定性一直是開發(fā)者非常關(guān)注的話題。隨著業(yè)務(wù)從單體架構(gòu)向分布式架構(gòu)演進(jìn)以及部署方式的變化,服務(wù)之間的依賴關(guān)系變得越來越復(fù)雜,業(yè)務(wù)系統(tǒng)也面臨著巨大的高可用挑戰(zhàn)。
在生產(chǎn)環(huán)境中大家可能遇到過各種不穩(wěn)定的情況,比如:
- 大促時(shí)瞬間洪峰流量導(dǎo)致系統(tǒng)超出最大負(fù)載,load 飆高,系統(tǒng)崩潰導(dǎo)致用戶無法下單。
- “黑馬”熱點(diǎn)商品擊穿緩存,DB 被打垮,擠占正常流量。
- 調(diào)用端被不穩(wěn)定第三方服務(wù)拖垮,線程池被占滿,調(diào)用堆積,導(dǎo)致整個(gè)調(diào)用鏈路卡死。
這些不穩(wěn)定的場景可能會導(dǎo)致嚴(yán)重后果,但很多時(shí)候我們又容易忽視這些與流量/依賴相關(guān)的高可用防護(hù)。大家可能想問:如何預(yù)防這些不穩(wěn)定因素帶來的影響?如何針對流量進(jìn)行高可用的防護(hù)?如何保障服務(wù)“穩(wěn)如磐石”?這時(shí)候我們就要請出阿里雙十一同款的高可用防護(hù)中間件 —— Sentinel。在今年剛剛過去的天貓 雙11 大促中,Sentinel 完美地保障了阿里成千上萬服務(wù) 雙11 峰值流量的穩(wěn)定性,同時(shí) Sentinel Go 版本也在近期正式宣布 GA。下面我們來一起了解下 Sentinel Go 的核心場景以及社區(qū)在云原生方面的探索。
Sentinel 介紹
Sentinel 是阿里巴巴開源的,面向分布式服務(wù)架構(gòu)的流量控制組件,主要以流量為切入點(diǎn),從限流、流量整形、熔斷降級、系統(tǒng)自適應(yīng)保護(hù)等多個(gè)維度來幫助開發(fā)者保障微服務(wù)的穩(wěn)定性。Sentinel 承接了阿里巴巴近 10 年的 雙11 大促流量的核心場景,例如秒殺、冷啟動、消息削峰填谷、集群流量控制、實(shí)時(shí)熔斷下游不可用服務(wù)等,是保障微服務(wù)高可用的利器,原生支持 Java/Go/C++ 等多種語言,并且提供 Istio/Envoy 全局流控支持來為 Service Mesh 提供高可用防護(hù)的能力。
今年年初,Sentinel 社區(qū)宣布了 Sentinel Go 版本的發(fā)布,為 Go 語言的微服務(wù)和基礎(chǔ)組件提供高可用防護(hù)和容錯(cuò)能力的原生支持,標(biāo)志著 Sentinel 朝著多元化與云原生邁出了新的一步。在這半年的時(shí)間內(nèi),社區(qū)推出了近 10 個(gè)版本,逐步對齊了核心高可用防護(hù)和容錯(cuò)能力,同時(shí)也在不斷擴(kuò)充開源生態(tài),與 dubbo-go、螞蟻 MOSN 等開源社區(qū)進(jìn)行共建。
就在近期,Sentinel Go 1.0 GA 版本正式發(fā)布,標(biāo)志著 Go 版本正式進(jìn)入生產(chǎn)可用階段。Sentinel Go 1.0 版本對齊了 Java 版本核心的高可用防護(hù)和容錯(cuò)能力,包括限流、流量整形、并發(fā)控制、熔斷降級、系統(tǒng)自適應(yīng)保護(hù)、熱點(diǎn)防護(hù)等特性。同時(shí) Go 版本已覆蓋主流開源生態(tài),提供了 Gin、gRPC、go-micro、dubbo-go 等常用微服務(wù)框架的適配,并提供了 etcd、Nacos、Consul 等動態(tài)數(shù)據(jù)源擴(kuò)展支持。Sentinel Go 也在朝著云原生的方向不斷演進(jìn),1.0 版本中也進(jìn)行了一些云原生方面的探索,包括 Kubernetes CRD data-source, Kubernetes HPA 等。對于 Sentinel Go 版本而言,我們期望的流控場景并不局限于微服務(wù)應(yīng)用本身。云原生基礎(chǔ)組件中 Go 語言生態(tài)占比較高,而這些云原生組件很多時(shí)候又缺乏細(xì)粒度、自適應(yīng)的保護(hù)與容錯(cuò)機(jī)制,這時(shí)候就可以結(jié)合組件的一些擴(kuò)展機(jī)制,利用 Sentinel Go 來保護(hù)自身的穩(wěn)定性。
Sentinel 底層通過高性能的滑動窗口進(jìn)行秒級調(diào)用指標(biāo)統(tǒng)計(jì),結(jié)合 token bucket, leaky bucket 和自適應(yīng)流控算法來透出核心的高可用防護(hù)能力。
那么我們?nèi)绾卫?Sentinel Go 來保證我們微服務(wù)的穩(wěn)定性?下面我們來看幾個(gè)典型的應(yīng)用場景。
高可用防護(hù)的核心場景
1. 流量控制與調(diào)配
流量是非常隨機(jī)性的、不可預(yù)測的。前一秒可能還風(fēng)平浪靜,后一秒可能就出現(xiàn)流量洪峰了(例如 雙11 零點(diǎn)的場景)。然而我們系統(tǒng)的容量總是有限的,如果突然而來的流量超過了系統(tǒng)的承受能力,就可能會導(dǎo)致請求處理不過來,堆積的請求處理緩慢,CPU/Load 飆高,最后導(dǎo)致系統(tǒng)崩潰。因此,我們需要針對這種突發(fā)的流量來進(jìn)行限制,在盡可能處理請求的同時(shí)來保障服務(wù)不被打垮,這就是流量控制。流量控制的場景是非常通用的,像脈沖流量類的場景都是適用的。
通常在 Web 入口或服務(wù)提供方(Service Provider)的場景下,我們需要保護(hù)服務(wù)提供方自身不被流量洪峰打垮。這時(shí)候通常根據(jù)服務(wù)提供方的服務(wù)能力進(jìn)行流量控制,或針對特定的服務(wù)調(diào)用方進(jìn)行限制。我們可以結(jié)合前期壓測評估核心接口的承受能力,配置 QPS 模式的流控規(guī)則,當(dāng)每秒的請求量超過設(shè)定的閾值時(shí),會自動拒絕多余的請求。
下面是最簡單的一個(gè) Sentinel 限流規(guī)則的配置示例:
_, err = flow.LoadRules([]*flow.Rule{{Resource: "some-service", // 埋點(diǎn)資源名Count: 10, // 閾值為 10,默認(rèn)為秒級維度統(tǒng)計(jì),即該請求單機(jī)每秒不超過 10 次ControlBehavior: flow.Reject, // 控制效果為直接拒絕,不控制請求之間的時(shí)間間隔,不排隊(duì)}, })2. Warm-Up 預(yù)熱流控
當(dāng)系統(tǒng)長期處于低水位的情況下,流量突然增加時(shí),直接把系統(tǒng)拉升到高水位可能瞬間把系統(tǒng)壓垮。比如剛啟動的服務(wù),數(shù)據(jù)庫連接池可能還未初始化,緩存也處于空的狀態(tài),這時(shí)候激增的流量非常容易導(dǎo)致服務(wù)崩潰。如果采用傳統(tǒng)的限流模式,不加以平滑/削峰限制,其實(shí)也是有被打掛的風(fēng)險(xiǎn)的(比如一瞬間并發(fā)很高)。針對這種場景,我們就可以利用 Sentinel 的 Warm-Up 流控模式,控制通過的流量緩慢增加,在一定時(shí)間內(nèi)逐漸增加到閾值上限,而不是在一瞬間全部放行,同時(shí)結(jié)合請求間隔控制+排隊(duì)的控制效果 來防止大量請求都在同一時(shí)刻被處理。這樣可以給冷系統(tǒng)一個(gè)預(yù)熱的時(shí)間,避免冷系統(tǒng)被壓垮。
3. 并發(fā)控制與熔斷降級
一個(gè)服務(wù)常常會調(diào)用別的模塊,可能是另外的一個(gè)遠(yuǎn)程服務(wù)、數(shù)據(jù)庫,或者第三方 API 等。例如,支付的時(shí)候,可能需要遠(yuǎn)程調(diào)用銀聯(lián)提供的 API;查詢某個(gè)商品的價(jià)格,可能需要進(jìn)行數(shù)據(jù)庫查詢。然而,這個(gè)被依賴服務(wù)的穩(wěn)定性是不能保證的。如果依賴的服務(wù)出現(xiàn)了不穩(wěn)定的情況,請求的響應(yīng)時(shí)間變長,那么調(diào)用服務(wù)的方法的響應(yīng)時(shí)間也會變長,線程會產(chǎn)生堆積,最終可能耗盡業(yè)務(wù)自身的線程池,服務(wù)本身也變得不可用。
現(xiàn)代微服務(wù)架構(gòu)都是分布式的,由非常多的服務(wù)組成。不同服務(wù)之間相互調(diào)用,組成復(fù)雜的調(diào)用鏈路。以上的問題在鏈路調(diào)用中會產(chǎn)生放大的效果。復(fù)雜鏈路上的某一環(huán)不穩(wěn)定,就可能會層層級聯(lián),最終導(dǎo)致整個(gè)鏈路都不可用。Sentinel Go 提供以下的能力避免慢調(diào)用等不穩(wěn)定因素造成不可用:
- 并發(fā)控制(isolation 模塊):作為一種輕量級隔離的手段,控制某些調(diào)用的并發(fā)數(shù)(即正在進(jìn)行的數(shù)目),防止過多的慢調(diào)用擠占正常的調(diào)用。
- 熔斷降級(circuitbreaker 模塊):對不穩(wěn)定的弱依賴調(diào)用進(jìn)行自動熔斷降級,暫時(shí)切斷不穩(wěn)定調(diào)用,避免局部不穩(wěn)定因素導(dǎo)致整體的雪崩。
Sentinel Go 熔斷降級特性基于熔斷器模式的思想,在服務(wù)出現(xiàn)不穩(wěn)定因素(如響應(yīng)時(shí)間變長,錯(cuò)誤率上升)的時(shí)候暫時(shí)切斷服務(wù)的調(diào)用,等待一段時(shí)間再進(jìn)行嘗試。一方面防止給不穩(wěn)定服務(wù)“雪上加霜”,另一方面保護(hù)服務(wù)的調(diào)用方不被拖垮。Sentinel 支持兩種熔斷策略:基于響應(yīng)時(shí)間(慢調(diào)用比例)和基于錯(cuò)誤(錯(cuò)誤比例/錯(cuò)誤數(shù)),可以有效地針對各種不穩(wěn)定的場景進(jìn)行防護(hù)。
注意熔斷器模式一般適用于弱依賴調(diào)用,即降級后不影響業(yè)務(wù)主流程,開發(fā)者需要設(shè)計(jì)好降級后的 fallback 邏輯和返回值。另外需要注意的是,即使服務(wù)調(diào)用方引入了熔斷降級機(jī)制,我們還是需要在 HTTP 或 RPC 客戶端配置請求超時(shí)時(shí)間,來做一個(gè)兜底的防護(hù)。
4. 熱點(diǎn)防護(hù)
流量是隨機(jī)的,不可預(yù)測的。為了防止被大流量打垮,我們通常會對核心接口配置限流規(guī)則,但有的場景下配置普通的流控規(guī)則是不夠的。我們來看這樣一種場景——大促峰值的時(shí)候,總是會有不少“熱點(diǎn)”商品,這些熱點(diǎn)商品的瞬時(shí)訪問量非常高。一般情況下,我們可以事先預(yù)測一波熱點(diǎn)商品,并對這些商品信息進(jìn)行緩存“預(yù)熱”,以便在出現(xiàn)大量訪問時(shí)可以快速返回而不會都打到 DB 上。但每次大促都會涌現(xiàn)出一些“黑馬”商品,這些“黑馬”商品是我們無法事先預(yù)測的,沒有被預(yù)熱。當(dāng)這些“黑馬”商品訪問量激增時(shí),大量的請求會擊穿緩存,直接打到 DB 層,導(dǎo)致 DB 訪問緩慢,擠占正常商品請求的資源池,最后可能會導(dǎo)致系統(tǒng)掛掉。這時(shí)候,利用 Sentinel 的熱點(diǎn)參數(shù)流量控制,自動識別熱點(diǎn)參數(shù)并控制每個(gè)熱點(diǎn)值的訪問 QPS 或并發(fā)量,可以有效地防止過“熱”的參數(shù)訪問擠占正常的調(diào)用資源。
再比如有的場景下我們希望限制每個(gè)用戶調(diào)用某個(gè) API 的頻率,將 API 名稱+userId 作為埋點(diǎn)資源名顯然是不合適的。這時(shí)候我們可以在給 API 埋點(diǎn)的時(shí)候通過 WithArgs(xxx) 將 userId 作為參數(shù)傳入到 API 埋點(diǎn)中,然后配置熱點(diǎn)規(guī)則即可針對每個(gè)用戶分別限制調(diào)用頻率;同時(shí),Sentinel 也支持針對某些具體值單獨(dú)配置限流值,進(jìn)行精細(xì)化流控。像其他規(guī)則一樣,熱點(diǎn)流控規(guī)則同樣支持通過動態(tài)數(shù)據(jù)源進(jìn)行動態(tài)配置。
Sentinel Go 提供的 RPC 框架整合模塊(如 Dubbo、gRPC)均會自動將 RPC 調(diào)用的參數(shù)列表附帶在埋點(diǎn)中,用戶可以直接針對相應(yīng)的參數(shù)位置配置熱點(diǎn)流控規(guī)則。注意如果需要配置具體值限流,受類型系統(tǒng)限制,目前僅支持基本類型和 string 類型。
Sentinel Go 的熱點(diǎn)流量控制基于緩存淘汰機(jī)制+令牌桶機(jī)制實(shí)現(xiàn)。Sentinel 通過淘汰機(jī)制(如 LRU、LFU、ARC 策略等)來識別熱點(diǎn)參數(shù),通過令牌桶機(jī)制來控制每個(gè)熱點(diǎn)參數(shù)的訪問量。目前的 Sentinel Go 版本采用 LRU 策略統(tǒng)計(jì)熱點(diǎn)參數(shù),社區(qū)也已有貢獻(xiàn)者提交了優(yōu)化淘汰機(jī)制的 PR,在后續(xù)的版本中社區(qū)會引入更多的緩存淘汰機(jī)制來適配不同的場景。
5. 系統(tǒng)自適應(yīng)保護(hù)
有了以上的流量防護(hù)場景,是不是就萬事無憂了呢?其實(shí)不是的,很多時(shí)候我們無法事先就準(zhǔn)確評估某個(gè)接口的準(zhǔn)確容量,甚至無法預(yù)知核心接口的流量特征(如是否有脈沖情況),這時(shí)候靠事先配置的規(guī)則可能無法有效地保護(hù)當(dāng)前服務(wù)節(jié)點(diǎn);一些情況下我們可能突然發(fā)現(xiàn)機(jī)器的 Load 和 CPU usage 等開始飚高,但卻沒有辦法很快的確認(rèn)到是什么原因造成的,也來不及處理異常。這個(gè)時(shí)候我們其實(shí)需要做的是快速止損,先通過一些自動化的兜底防護(hù)手段,將瀕臨崩潰的微服務(wù)“拉”回來。針對這些情況,Sentinel Go 提供了一種系統(tǒng)自適應(yīng)保護(hù)規(guī)則,結(jié)合系統(tǒng)指標(biāo)和服務(wù)容量,自適應(yīng)動態(tài)調(diào)整流量。
Sentinel 系統(tǒng)自適應(yīng)保護(hù)策略借鑒了 TCP BBR 算法的思想,結(jié)合系統(tǒng)的 Load、CPU 使用率以及服務(wù)的入口 QPS、響應(yīng)時(shí)間和并發(fā)量等幾個(gè)維度的監(jiān)控指標(biāo),通過自適應(yīng)的流控策略,讓系統(tǒng)的入口流量和系統(tǒng)的負(fù)載達(dá)到一個(gè)平衡,讓系統(tǒng)盡可能跑在最大吞吐量的同時(shí)保證系統(tǒng)整體的穩(wěn)定性。系統(tǒng)規(guī)則可以作為整個(gè)服務(wù)的一個(gè)兜底防護(hù)策略,保障服務(wù)不掛,對 CPU 密集型的場景會有比較好的效果。同時(shí),社區(qū)也在結(jié)合自動化控制理論和強(qiáng)化學(xué)習(xí)等手段,持續(xù)完善自適應(yīng)流控的效果和適用場景。在未來的版本中,社區(qū)會也推出更多試驗(yàn)性的自適應(yīng)流控策略,來滿足更多的可用性場景。
云原生探索
云原生是 Sentinel Go 版本演進(jìn)最為重要的一環(huán)。在 GA 的過程中,Sentinel Go 社區(qū)也在 Kubernetes 和 Service Mesh 等場景下進(jìn)行了一些探索。
1. Kubernetes CRD data-source
在生產(chǎn)環(huán)境中我們一般都需要通過配置中心來動態(tài)管理各種規(guī)則配置。在 Kubernetes 集群中,我們可以天然利用 Kubernetes CRD 的方式來管理應(yīng)用的 Sentinel 規(guī)則。在 Go 1.0.0 版本中社區(qū)提供了基本的 Sentinel 規(guī)則 CRD 抽象以及相應(yīng)的 數(shù)據(jù)源實(shí)現(xiàn)。用戶只需要先導(dǎo)入 Sentinel 規(guī)則 CRD 定義文件,接入 Sentinel 時(shí)注冊對應(yīng)的 data-source,然后按照 CRD 定義的格式編寫 YAML 配置并 kubectl apply 到對應(yīng)的 namespace 下即可實(shí)現(xiàn)動態(tài)配置規(guī)則。以下是一個(gè)流控規(guī)則的示例:
apiVersion: datasource.sentinel.io/v1alpha1 kind: FlowRules metadata:name: foo-sentinel-flow-rules spec:rules:- resource: simple-resourcethreshold: 500- resource: something-to-smooththreshold: 100controlBehavior: ThrottlingmaxQueueingTimeMs: 500- resource: something-to-warmupthreshold: 200tokenCalculateStrategy: WarmUpcontrolBehavior: RejectwarmUpPeriodSec: 30warmUpColdFactor: 3Kubernetes CRD data-source 模塊地址:https://github.com/sentinel-group/sentinel-go-datasource-k8s-crd
后續(xù)社區(qū)會進(jìn)一步完善 Rule CRD 定義并與其它社區(qū)一起探討高可用防護(hù)相關(guān)的標(biāo)準(zhǔn)抽象。
2. Service Mesh
Service Mesh 是微服務(wù)向云原生演進(jìn)的趨勢之一。在 Service Mesh 架構(gòu)下,一些服務(wù)治理和策略控制的能力都逐漸下沉到了 data plane 層。去年 Sentinel 社區(qū)在 Java 1.7.0 版本里面做了一些嘗試,提供了 Envoy Global Rate Limiting gRPC Service 的實(shí)現(xiàn) —— Sentinel RLS token server,借助 Sentinel 集群限流 token server 來為 Envoy 服務(wù)網(wǎng)格提供集群流量控制的能力。今年隨著 Sentinel Go 版本的誕生,社區(qū)與更多的 Service Mesh 產(chǎn)品開展合作、整合。我們與螞蟻的 MOSN 社區(qū)進(jìn)行共建,在 MOSN Mesh 中原生支持了 Sentinel Go 的流控降級能力,同時(shí)也已在螞蟻內(nèi)部落地。社區(qū)也在探索更為通用的方案,如利用 Istio 的 Envoy WASM 擴(kuò)展機(jī)制實(shí)現(xiàn) Sentinel 插件,讓 Istio/Envoy 服務(wù)網(wǎng)格可以借助 Sentinel 原生的流控降級與自適應(yīng)保護(hù)的能力來保障整個(gè)集群服務(wù)的穩(wěn)定性。
3. Kubernetes HPA based on Sentinel metrics
保障服務(wù)穩(wěn)定性的方法多種多樣,除了各種規(guī)則對流量進(jìn)行“控制”之外,“彈性”也是一種思路。對于部署在 Kubernetes 中的應(yīng)用來說,可以利用 Kubernetes HPA 能力進(jìn)行對服務(wù)進(jìn)行水平擴(kuò)縮容。HPA 默認(rèn)支持多種系統(tǒng)指標(biāo),并且支持自定義指標(biāo)統(tǒng)計(jì)。目前我們已經(jīng)在阿里云 Kubernetes 容器服務(wù)上結(jié)合 AHAS Sentinel 支持基于服務(wù)的平均 QPS、響應(yīng)時(shí)間等作為條件進(jìn)行彈性伸縮。社區(qū)也正在這一塊做一些嘗試,將一些 Sentinel 的服務(wù)級別的指標(biāo)統(tǒng)計(jì)(通過量,拒絕量,響應(yīng)時(shí)間等)通過 Prometheus 或 OpenTelemetry 等標(biāo)準(zhǔn)方式透出,并適配到 Kubernetes HPA 中。
當(dāng)然基于 Sentinel 的彈性方案不是萬靈藥,它只適用于一些特定的場景,比如適用于啟動速度快的無狀態(tài)服務(wù)(Serverless 場景)。對于啟動較慢的服務(wù),或非本服務(wù)容量問題的場景(如依賴的 DB 容量不夠),彈性的方案不能很好地解決穩(wěn)定性的問題,甚至可能會加劇服務(wù)的惡化。
Let's start hacking!
了解了以上的高可用防護(hù)的場景,以及 Sentinel 在云原生方向的一些探索,相信大家對微服務(wù)容錯(cuò)與穩(wěn)定性的手段有了新的體會。歡迎大家動手玩一下 demo,將微服務(wù)接入 Sentinel 來享受高可用防護(hù)和容錯(cuò)的能力,讓服務(wù)“穩(wěn)如磐石”。同時(shí) Sentinel Go 1.0 GA 版本的發(fā)布離不開社區(qū)的貢獻(xiàn),感謝所有參與貢獻(xiàn)的小伙伴們。
本次 GA 我們也新加入了兩位給力的 committer —— @sanxun0325 和 @luckyxiaoqiang,兩位在 1.0 版本的演進(jìn)帶來了 Warm Up 流控、Nacos 動態(tài)數(shù)據(jù)源以及一系列功能改進(jìn)和性能優(yōu)化,非常積極地幫助社區(qū)答疑解惑以及 review 代碼。恭喜兩位!社區(qū)在未來版本中也會朝著云原生和自適應(yīng)智能化的方向不斷探索和演進(jìn),也歡迎更多的同學(xué)加入貢獻(xiàn)小組,一起參與 Sentinel 未來的演進(jìn),創(chuàng)造無限可能。我們鼓勵(lì)任何形式的貢獻(xiàn),包括但不限于:
- bug fix
- new features/improvements
- dashboard
- document/website
- test cases
開發(fā)者可以在 GitHub 上面的 good first issue 列表上挑選感興趣的 issue 來參與討論和貢獻(xiàn)。我們會重點(diǎn)關(guān)注積極參與貢獻(xiàn)的開發(fā)者,核心貢獻(xiàn)者會提名為 Committer,一起主導(dǎo)社區(qū)的發(fā)展。我們也歡迎大家有任何問題和建議,都可以通過 GitHub issue、Gitter 或釘釘群(群號:30150716)等渠道進(jìn)行交流。Now start hacking!
- Sentinel Go repo:https://github.com/alibaba/sentinel-golang
- 企業(yè)用戶歡迎進(jìn)行登記:https://github.com/alibaba/Sentinel/issues/18
- Sentinel 阿里云企業(yè)版:https://ahas.console.aliyun.com/
總結(jié)
以上是生活随笔為你收集整理的数据库降级_阿里 双11 同款流控降级组件 Sentinel Go 正式GA,云原生服务稳稳稳...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玛纽尔扫地机器人怎样_扫地机器人怎样选?
- 下一篇: 珠海 第十届亚洲机器人锦标赛_2016年