Sentinel 是阿里巴巴開源的,面向分佈式服務架構的流量控制組件,主要以流量爲切入點,從限流、流量整形、熔斷降級、系統自適應保護等多個維度來幫助開發者保障微服務的穩定性。Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺、冷啓動、消息削峯填谷、集羣流量控制、實時熔斷下游不可用服務等,是保障微服務高可用的利器,原生支持 Java/Go/C++ 等多種語言,而且提供 Istio/Envoy/SOFA MOSN 全局流控支持來爲 Service Mesh 提供高可用防禦的能力。html
近期,Sentinel Go 0.4.0 正式發佈,帶來了熱點參數流控特性,能夠自動識別統計傳入參數中的「熱點」參數值並分別進行流控,對於防刷、熱點商品訪問頻次控制等場景很是有用,是高可用流量防禦中重要的一環。下面咱們來了解一下熱點參數流控的場景和原理。git
流量是隨機的,不可預測的。爲了防止被大流量打垮,咱們一般會對核心接口配置限流規則,但有的場景下配置普通的流控規則是不夠的。咱們來看這樣一種場景——大促峯值的時候,老是會有很多「熱點」商品,這些熱點商品的瞬時訪問量很是高。通常狀況下,咱們能夠事先預測一波熱點商品,並對這些商品信息進行緩存「預熱」,以便在出現大量訪問時能夠快速返回而不會都打到 DB 上。但每次大促都會涌現出一些「黑馬」商品,這些「黑馬」商品是咱們沒法事先預測的,沒有被預熱。當這些「黑馬」商品訪問量激增時,大量的請求會擊穿緩存,直接打到 DB 層,致使 DB 訪問緩慢,擠佔正常商品請求的資源池,最後可能會致使系統掛掉。這時候,利用 Sentinel 的熱點參數流量控制能力,自動識別熱點參數並控制每一個熱點值的訪問 QPS 或併發量,能夠有效地防止過「熱」的參數訪問擠佔正常的調用資源。github
再好比有的場景下咱們但願限制每一個用戶調用某個 API 的頻率,將 API 名稱+userId 做爲埋點資源名顯然是不合適的。這時候咱們能夠在給 API 埋點的時候經過 WithArgs(xxx)
將 userId 做爲參數傳入到 API 埋點中,而後配置熱點規則便可針對每一個用戶分別限制調用頻率;同時,Sentinel 也支持針對某些具體值單獨配置限流值,進行精細化流控。golang
熱點參數埋點/規則示例:api
// 埋點示例
e, b := sentinel.Entry("my-api", sentinel.WithArgs(rand.Uint32()%3000, "sentinel", uuid.New().String()))
// 規則示例
_, err = hotspot.LoadRules([]*hotspot.Rule{
{
Resource: "my-api",
MetricType: hotspot.QPS, // 請求量模式
ControlBehavior: hotspot.Reject,
ParamIndex: 0, // 參數索引,0 即爲第一個參數
Threshold: 50, // 針對每一個熱點參數值的閾值
BurstCount: 0,
DurationInSec: 1, // 統計窗口時長,這裏爲 1s
SpecificItems: map[hotspot.SpecificValue]int64{
// 支持針對某個具體值單獨配置限流值,好比這裏針對數值 9 限制請求量=0(不容許經過)
{ValKind: hotspot.KindInt, ValStr: "9"}: 0,
},
},
})
複製代碼
像其餘規則同樣,熱點流控規則一樣支持經過動態數據源進行動態配置。緩存
Sentinel Go 提供的 RPC 框架整合模塊(如 Dubbo、gRPC)均會自動將 RPC 調用的參數列表附帶在埋點中,用戶能夠直接針對相應的參數位置配置熱點流控規則。目前熱點規則僅支持基本類型和字符串類型,後續社區會進一步進行完善,支持更多的類型。架構
Sentinel Go 的熱點流量控制基於緩存淘汰機制+令牌桶機制實現。Sentinel 經過淘汰機制(如 LRU、LFU、ARC 策略等)來識別熱點參數,經過令牌桶機制來控制每一個熱點參數的訪問量。目前 0.4.0 版本採用 LRU 策略統計熱點參數,在後續的版本中社區會引入更多的緩存淘汰機制來適配不一樣的場景。併發
在服務提供方(Service Provider)的場景下,咱們須要保護服務提供方不被流量洪峯打垮。咱們一般根據服務提供方的服務能力進行流量控制,或針對特定的服務調用方進行限制。爲了保護服務提供方不被激增的流量拖垮影響穩定性,咱們能夠結合前期的容量評估,經過 Sentinel 配置 QPS 模式的流控規則,當每秒的請求量超過設定的閾值時,會自動拒絕多餘的請求。同時能夠結合熱點參數流控進行細粒度的流量防禦。框架
在服務調用端(Service Consumer)的場景下,咱們須要保護服務調用方不被不穩定的依賴服務拖垮。藉助 Sentinel 的信號量隔離策略(併發數流控規則),限制某個服務調用的併發量,防止大量慢調用擠佔正常請求的資源;同時,藉助熔斷降級規則,當異常比率或業務慢調用比例超過某個閾值後將調用自動熔斷,直到一段時間事後再嘗試恢復。熔斷期間咱們能夠提供默認的處理邏輯(fallback),熔斷期間的調用都會返回 fallback 的結果,而不會再去嘗試本已很是不穩定的服務。須要注意的是,即便服務調用方引入了熔斷降級機制,咱們仍是須要在 HTTP 或 RPC 客戶端配置請求超時時間,來作一個兜底的保護。分佈式
在一些請求突刺的場景中,好比 MQ 客戶端消費消息的場景,咱們可能不但願將多餘的消息直接拒絕(重投),而是讓這些過量的消息排隊逐步處理。這就是「削峯填谷」的場景。咱們能夠利用 Sentinel 流控規則中的「勻速+排隊等待」控制效果來處理這種場景,以固定的間隔時間讓請求經過,超出預設量的請求排隊等待。這種方式適合用於請求以突刺狀來到,這個時候咱們不但願一會兒把全部的請求都經過,這樣可能會把系統壓垮;同時咱們也期待系統以穩定的速度,逐步處理這些請求,以起到「削峯填谷」的效果,而不是直接拒絕全部多餘的請求。
同時 Sentinel Go 還提供 全局維度的系統自適應保護能力,結合系統的 Load、CPU 使用率以及服務的入口 QPS、響應時間和併發量等幾個維度的監控指標,經過自適應的流控策略,讓系統的入口流量和系統的負載達到一個平衡,讓系統儘量跑在最大吞吐量的同時保證系統總體的穩定性。系統規則能夠做爲整個服務的一個兜底防禦策略,保障服務不掛。
Sentinel Go 版本正在快速演進中,咱們很是歡迎感興趣的開發者參與貢獻,一塊兒來主導將來版本的演進。Sentinel Go 版本的演進離不開社區的貢獻。若您有意願參與貢獻,歡迎聯繫咱們加入 Sentinel 貢獻小組一塊兒成長(Sentinel 開源討論釘釘羣:30150716)。咱們會按期給活躍貢獻者寄送小禮品,核心貢獻者能夠提名爲 committer,一塊兒主導社區的演進。同時,也歡迎你們經過 AHAS Sentinel 控制檯 來快速體驗 Sentinel 的能力。Now let's start hacking!