文章目錄
- 1. 基礎知識
- 2. 數據源使用
- 2.1 RedisDatasource
- 2.2 ZookeeperDatasource
1. 基礎知識
流量控制規則(FlowRule):
- 閾值類型grade:
- 0(并發線程數):限制同時處理請求的線程
- 1(QPS):限制每秒請求數
- 閾值count:單機閾值,如QPS=100,并發線程數=10
- 流控模式strategy:
- 0(直接模式):達到閾值即限流,默認
- 1(關聯模式):關聯資源超閾值時限流本資源,如支付接口超限,限制下單接口
- 2(鏈路模式):僅統計指定入口的流量
- 流控效果controlBehavior:
- 0(快速失敗):超閾值直接拒絕,默認
- 1(預熱啟動):在規定的時間內從下限逐步提升到上限(如3s從3QPS升至10QPS),冷啟動因子默認為3,即閾值是100QPS,初始QPS為30
- 2(勻速排隊):請求按固定間隔通過(漏桶算法),需要設置超時時間
- 3(預熱勻速排隊):預熱階段多出的請求勻速排隊,進入正常階段繼續使用勻速排隊處理請求
- 規則管理類:以resource資源名稱為key,流量控制規則為value管理在FlowRuleManager
- 實際流量控制邏輯:加載規則時會根據controlBehavior屬性創建對應的流量控制器,指標從節點中獲取,在流量控制器中進行規則判斷
- 默認流控DefaultController:處理線程流控及QPS快速失敗流控
- 預熱啟動WarmUpController:處理QPS的預熱啟動流控
- 勻速排隊RateLimiterController:處理QPS的勻速排隊流控
- 預熱勻速排WarmUpRateLimiterController:處理QPS的預熱勻速排隊流控
熔斷降級規則(DegradeRule):
- 熔斷策略grade:
- 0(慢調用比例):在統計窗口內調用時間大于判定時間,且在窗口內比例大于慢調用閾值則熔斷
- 1(異常比例):在統計窗口內拋異常的數量占比大于總請求數則熔斷
- 2(異常數):在統計窗口內拋異常的數大于閾值則熔斷
- 熔斷閾值count:分別對應慢調用時間閾值、異常比例閾值、異常數量閾值
- 熔斷時間timeWindow:熔斷持續時間(秒),超時后進入半開狀態試探
- 最小請求數minRequestAmount:在統計窗口內觸發熔斷的最小請求數
- 統計窗口statIntervalMs:統計窗口時間,單位毫秒
- 慢調用比例閾值slowRatioThreshold:僅慢調用模式生效,0.0~1.0
- 規則管理類:以resource資源名稱為key,熔斷降級規則為value管理在DegradeRuleManager
- 實際熔斷降級邏輯:加載規則時會根據grade屬性創建對應的斷路器(CircuitBreaker),在斷路器中記錄指標和判斷規則
- 響應時間斷路器ResponseTimeCircuitBreaker:grade=0,記錄超時請求數和總請求數進行判斷
- 異常斷路器ExceptionCircuitBreaker:grade=1或2,記錄失敗次數和總請次數進行判斷
Sentinel規則可以從Nacos、Apollo、Zookeeper、Consul、Redis或讀取文件獲取,基本涵蓋了國內常的幾個持久化數據框架
sentinel的數據源配置時可自定義key名稱,value為對應的數據源配置,如下:
spring:cloud:sentinel:customDb1:zk:server-addr: localhost:xxxxpath: xxxxxxxx/xxxxrule-type: flowfixDb2:redis:host: localhostport: 6379password: xxxxxxrule-type: degrade
配置單個數據源只能獲取一種類型的規則,如要獲取flow和degrade規則,則數據源需要配置兩次,分別指定ruleType類型獲取
數據源常用的ruleType有:
- flow:流量控制,對應FlowRule
- degrade:熔斷限流,對應DegradeRule
- param-flow:熱點參數流量控制,對應ParamFlowRule
- system:系統指標控制,對應SystemRule
當從數據源拉取數據后,需要將數據源的數據格式轉化為對應的規則格式,官方默認的格式要求是json,額外支持xml格式,由數據源的dataType屬性控制
若需要自定義數據格式,并轉換為對應的規則類型,有兩種方式:
- 僅指定dataType:
- 前置條件:如轉換properties文件
- dataType=properties
- 實現sentinel的Converter接口
- 實現類需要注冊beanName到spring容器中
- 名稱規則:beanName=
sentinel-{dataType}-{ruleType}-converter
- 名稱示例:
sentinel-properties-flow-converter
代表支持使用dataType=properties的Converter實現類 - 官方支持的dataType:
- json:sentinel-json-flow-converter、sentinel-json-degrade-converter等
- xml:sentinel-xml-flow-converter、sentinel-xml-degrade-converter等
- 前置條件:如轉換properties文件
- 自定義dataType:
- 前置條件
- dataType=custom
- 配置converterClass
- 實現sentinel的Converter接口
- 實現類需要注冊beanName到spring容器中
- 名稱規則:beanName=
sentinel-{converterClass}
- 實現效果:從指定數據源拉取到數據后使用converterClass對應實現類轉換數據為規則列表
- 前置條件
2. 數據源使用
Nacos、Apollo和Consul要求程序必須使用這三個分布式數據框架,適用性較低。Redis和Zookeeper大部分中間件都會依賴,因此這兩種方式更具有普遍實用價值
2.1 RedisDatasource
使用redis需要配置下面幾個關鍵屬性:
- host:地址
- port:端口
- password:連接密碼
- ruleKey:初始化時拉取規則的key
- channel:使用Pub/Sub機制訂閱的channel,要求發布者往該channel發布消息
配置完redis數據源后會注冊RedisDataSourceFactoryBean到spring容器中,在工廠bean中初始化RedisDataSource
初始化數據源時使用ruleKey從redis拉取對應的鍵值,再使用對應的converter轉化數據格式給對應的規則管理類加載使用
后續規則更新時,不僅要求規則更新系統修改ruleKey對應的鍵值,還需要系統使用redis的Pub/Sub機制往channel發送最新規則值,這樣依賴系統才會使用最新規則數據
Pub/Sub機制擁有諸多缺陷,因此在Sentinel沒有把通知機制修改為Stream前,不太推薦使用RedisDatasource來作為中間件存儲規則
2.2 ZookeeperDatasource
使用zookeeper只需要配置兩個關鍵屬性:
- serverAddr:完整的連接地址端口
- path:對應的獲取/監聽數據節點路徑
配置path相當于直接指定了完整的zk節點,除了這種外還有另一種配置方式:使用groupId和dataId代替path。其等效于path=/{groupId}/{dataId}
,若配置了groupId和dataId,則優先使用該方式
配置完zk數據源后會注冊ZookeeperDataSourceFactoryBean到spring容器中,在工廠中初始化ZookeeperDataSource
初始化數據源時會使用Curator連接zk,使用NodeCache監聽對應路徑的數據節點,當數據節點發生變化時則觸發更新
連接zk成功后將會使用NodeCache獲取監聽節點數據
當獲得數據節點數據后,會使用converter轉換為對應規則,最后再把規則給對應規則管理器加載使用
若項目沒有使用Nacos、Apollo,相對Redis,更推薦使用zk來作為中間件發布規則數據