享學課堂特邀作者:老顧
轉載請宣告出處!!!
前言
之前老顧介紹了gateway集合sentinel1.8的整體概念介紹,今天老顧就來介紹一下,gateway如何與sentinel相結合,**sentinel1.8降級規則的變化,**以及dashboard原始碼的bug,
POM依賴
我們先創建一個gateway專案,要與Sentinel結合需要依賴一下jar包,
說明一下老顧把以前文章中的案例依賴的jar包進行了升級,針對SpringCloud Alibaba的版本需要升級到2.2.3.RELEASE版本;spring boot也升級到了2.3.3.RELEASE;spring cloud升級到Hoxton.SR8
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
不要搞錯了哦,網上有些資料有坑
配置
網關專案中增加一個配置類,我們需要添加一個SentinelGatewayFilter和SentinelGatewayBlockExceptionHandler實體
下載并安裝sentinel-dashboard
之前老顧的文章已經介紹過了
1、下載地址:https://github.com/alibaba/Sentinel/releases根據自己需要下載對應版本,這里以sentinel-dashboard-1.8.0.jar為例
2、上傳控制臺jar包至linux服務器,啟動sentinel控制臺命(埠被占用請修改埠):
nohup java -Dserver.port=8081 -Dcsp.sentinel.dashboard.server=localhost:8081 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar &
3、訪問后臺:http://localhost:8081,用戶名、密碼默認都為:sentinel,也可在啟動命令中自行配置
網關啟動引數
為網關增加JVM啟動引數
-Dcsp.sentinel.dashboard.server=localhost:8081
-Dproject.name=qy-tribe-gateway
-Dcsp.sentinel.api.port=8719
-Dcsp.sentinel.app.type=1
引數說明: -Dcsp.sentinel.dashboard.server:指定控制臺地址和埠,
-Dproject.name:在sentinel控制臺中展示的專案名稱,
-Dcsp.sentinel.api.port:指定客戶端監控 API 的埠(默認是 8719),如控制臺修改規則,則會向該埠推送規則資訊,
-Dcsp.sentinel.app.type:從 1.6.3 版本開始,控制臺支持網關流控規則管理,該啟動引數會將您的服務標記為 API Gateway,在接入控制臺時您的服務會自動注冊為網關型別,然后您即可在控制臺配置網關規則和 API 分組,
配置方案
上面的jvm啟動引數,另一個方案就是在yml組態檔中配置
##Sentinel 控制臺地址
spring.cloud.sentinel.transport.dashboard = localhost:8081
##客戶端監控API的埠
spring.cloud.sentinel.transport.port = 8719
##取消Sentinel控制臺懶加載,即專案啟動即連接
sentinelspring.cloud.sentinel.eager = true
上面的dashboard地址的配置,以及transport.port配置和用啟動引數的方案是一樣的效果,
注意:網上有些資料說spring.cloud.sentinel.app.type = 1 可以標示為網關專案,但親測驗無效,所以必須在啟動網關專案的時候,一定要加上-Dcsp.sentinel.app.type=1

我們發現網關專案的Sentinel選單和普通微服務專案選單是不一樣的,小伙伴們要記住哦,
API 分組和route維度
Sentinel 1.6.0引入了Sentinel API Gateway Adapter Common模塊,此模塊中包含網關限流的規則和自定義 API 的物體和管理邏輯:
1、GatewayFlowRule:網關限流規則,這個根據網關的自身的路由場景設計的,可以針對不同 route 或自定義的 API 分組進行限流,支持針對請求中的引數、Header、來源 IP 等進行定制化的限流,
2、ApiDefinition:用戶自定義的 API 定義分組,可以看做是一些 URL 匹配的組合,比如我們可以定義一個 API 叫 myapi,請求 path 模式為 /foo/* 和 /baz/* 的都歸到 myapi 這個 API 分組下面,限流的時候可以針對這個自定義的 API 分組維度進行限流,
網關限流規則 GatewayFlowRule

欄位解釋如下:
1、resourceMode:API型別
規則是針對 API Gateway 的route(RESOURCEMODEROUTEID)還是用戶在 Sentinel 中自定義的API 分組(RESOURCEMODECUSTOMAPINAME),默認是route,
2、resource:API名稱
網關中的 route 名稱或者用戶自定義的API 分組名稱,
3、請求屬性:可選,paramItem引數限流配置,
若不提供,則代表不針對引數進行限流,該網關規則將會被轉換成普通流控規則;否則會轉換成熱點規則,
其中的欄位:parseStrategy:從請求中提取引數的策略,目前支持五種模式提取來源 IP 、Host 、 Header 、 URL 引數、Cookie pattern 和 matchStrategy:為引數匹配特性預留,匹配模式,匹配串 fieldName:若提取策略選擇 Header 模式或 URL 引數模式,則需要指定對應的 header 名稱或 URL 引數名稱,

4、grade:閾值型別
限流閾值型別,是按照 QPS 還是執行緒數
5、count:限流閾值
6、intervalSec:間隔時間
統計時間視窗,單位是秒,默認是1 秒
7、controlBehavior:流控方式
目前支持快速失敗和勻速排隊兩種模式,默認是快速失敗,
8、burst
應對突發請求時額外允許的請求數目
9、maxQueueingTimeoutMs
勻速排隊模式下的最長排隊時間,單位是毫秒,僅在勻速排隊模式下生效,
網關流控實作原理

上圖的整體流程如下:
1、外部請求進入API Gateway時會經過Sentinel實作的filter,其中會依次進行 路由/API 分組匹配、請求屬性決議和引陣列裝,
2、Sentinel 會根據配置的網關流控規則來決議請求屬性,并依照引數索引順序組裝引數陣列,最終傳入SphU.entry(res, args) 中,
3、Sentinel API Gateway Adapter Common模塊向 Slot Chain 中添加了一個 GatewayFlowSlot,專門用來做網關規則的檢查,
4、GatewayFlowSlot會從GatewayRuleManager中提取生成的熱點引數規則,根據傳入的引數依次進行規則檢查,若某條規則不針對請求屬性,則會在引數最后一個位置置入預設的常量,達到普通流控的效果,注意:
當通過 GatewayRuleManager 加載網關流控規則GatewayFlowRule時,無論是否針對請求屬性進行限流,Sentinel底層都會將網關流控規則轉化為熱點引數規則ParamFlowRule,存盤在GatewayRuleManager 中,與正常的熱點引數規則相隔離,轉換時Sentinel會根據請求屬性配置,為網關流控規則設定引數索引idx,并同步到生成的熱點引數規則中
熔斷降級

Sentinel在1.8.0版本對熔斷降級做了大的調整,可以定義任意時長的熔斷時間,引入了半開啟恢復支持,下面梳理下相關特性,
一、熔斷狀態
熔斷有三種狀態,分別為OPEN、HALF_OPEN、CLOSED

二、熔斷策略
熔斷降級支持慢呼叫比例、例外比例、例外數三種熔斷策略,
先明確下面兩個概念:慢呼叫:指耗時大于閾值RT的請求稱為慢呼叫,閾值RT由用戶設定
**最小請求數:**允許通過的最小請求數量,在最小請求數量內不發生熔斷,由用戶設定
1.慢呼叫比例

執行邏輯
熔斷(OPEN):請求數大于最小請求數并且慢呼叫的比率大于比例閾值則發生熔斷,熔斷時長為用戶自定義設定,
探測(HALFOPEN):當熔斷過了定義的熔斷時長,狀態由熔斷(OPEN)變為探測(HALFOPEN),
- 如果接下來的一個請求小于最大RT,說明慢呼叫已經恢復,結束熔斷,狀態由探測(HALF_OPEN)變更為關閉(CLOSED)
- 如果接下來的一個請求大于最大RT,說明慢呼叫未恢復,繼續熔斷,熔斷時長保持一致
注意Sentinel默認統計的RT上限是4900ms,超出此閾值的都會算作4900ms,若需要變更此上限可以通過啟動配置項-Dcsp.sentinel.statistic.max.rt=xxx來配置
2.例外比例
通過計算例外比例與設定閾值對比的一種策略,
當資源的每秒請求數大于等于最小請求數,并且例外總數占通過量的比例超過比例閾值時,資源進入降級狀態,

執行邏輯
熔斷(OPEN):當請求數大于最小請求并且例外比例大于設定的閾值時觸發熔斷,熔斷時長由用戶設定,
探測(HALFOPEN):當超過熔斷時長時,由熔斷(OPEN)轉為探測(HALFOPEN)
- 如果接下來的一個請求未發生錯誤,說明應用恢復,結束熔斷,狀態由探測(HALF_OPEN)變更為關閉(CLOSED)
- 如果接下來的一個請求繼續發生錯誤,說明應用未恢復,繼續熔斷,熔斷時長保持一致
3.例外數
通過計算發生例外的請求數與設定閾值對比的一種策略
當資源近1分鐘的例外數目超過閾值(例外數)之后會進行服務降級,注意由于統計時間視窗是分鐘級別的,若熔斷時長小于60s,則結束熔斷狀態后仍可能再次進入熔斷狀態,


執行邏輯
熔斷(OPEN):當請求數大于最小請求并且例外數量大于設定的閾值時觸發熔斷,熔斷時長由用戶設定,
**探測(HALFOPEN):**當超過熔斷時長時,由熔斷(OPEN)轉為探測(HALFOPEN)
- 如果接下來的一個請求未發生錯誤,說明應用恢復,結束熔斷,狀態由探測(HALF_OPEN)變更為關閉(CLOSED)
- 如果接下來的一個請求繼續發生錯誤,說明應用未恢復,繼續熔斷,熔斷時長保持一致
規則引數說明
熔斷降級DegradeRule中的屬性進行說明
Dashboard原始碼Bug
上面的規格引數中有個statIntervalMs這個屬性默認1000ms,統計時長無法在dashboard中進行修改,
注意:1.8版本的Sentinel dashboard降級頁面有個bug,就是統計時長屬性維護 丟失,有望再下一個版本中修復;也可以自行修改dashboard原始碼
修改/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/degrade-rule-dialog.html
增加一段html代碼,統計時長代碼
<div class="form-group">
<label class="col-sm-2 control-label">統計時長</label>
<div class="col-sm-4">
<div class="input-group">
<input type='number' min="1" class="form-control highlight-border" ng-model='currentRule.statIntervalMs'
placeholder="統計時長(ms)" />
<span class="input-group-addon">ms</span>
</div>
</div>
</div>
例外處理
當觸發限流后頁面顯示的是Blocked by Sentinel: FlowException,
這個原理是DefaultBlockRequestHandler;實作了BlockRequesthandler介面

為了展示更加友好的限流提示, Sentinel支持自定義例外處理,
可以在GatewayCallbackManager注冊回呼進行定制:
setBlockHandler :注冊函式用于實作自定義的邏輯處理被限流的請求,對應介面為 BlockRequestHandler ,默認實作為 DefaultBlockRequestHandler ,當被限流時會回傳類似 于下面的錯誤資訊:Blocked by Sentinel: FlowException ,
方案一:yml配置
spring.cloud.sentinel.scg.fallback.mode = response
spring.cloud.sentinel.scg.fallback.response-body = '{"code":403,"mes":"限流了"}'
上面的配置就可以達到自定義例外的效果,
方案二:注入Bean
總結
Sentinel1.8對降級的重新進行的改造,變化相對比較大,小伙伴們需要進行詳細學習哦!!!下面老顧會介紹Sentinel的規則持久化,對原始碼進行相應的改造,謝謝!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/202549.html
標籤:其他
