可视化界面 Sentinel 流控卫兵 限流 熔断 系统保护
Sentinel 流控衛兵
Sentinel分為兩個部分:
核心庫(Java客戶端):客戶端調用通用的應用
控制臺(Dashboard):基于springboot開發的,打包后可以直接運行,不需要額外的tomcat或其他容器
文章目錄
- Sentinel 流控衛兵
- 1. 認識Sentinel
- 1.1. 官網說明
- 1.2. 對比Hystrix
- 2. Sentinel應用啟動
- 3. 服務集成Sentinel
- 4. 流控設置
- 4.1. QPS限流
- 4.2. 線程限流
- 4.3. 流控的關聯模式
- 4.4. Warm up
- 4.5. 限流隊列
- 5. 熔斷降級
- 5.1. RT降級
- 5.2. 異常比例
- 5.3. 異常數
- 6. 熱點參數限流
- 6.1. 基本配置
- 6.2. 高級配置
- 7. 系統規則
- 8. @SentinelResource
- 8.1. 自定義blockhandler
- 8.2. 自定義fallback
- 8.3. fallback異常忽略
- 9. Sentinel和Feign的集成
- 10. Sentinel規則持久化
1. 認識Sentinel
1.1. 官網說明
https://github.com/alibaba/Sentinel/wiki/介紹Sentinel分為兩個部分:
- 核心庫(Java客戶端):客戶端調用通用的應用
- 控制臺(Dashboard):基于springboot開發的,打包后可以直接運行,不需要額外的tomcat或其他容器
1.2. 對比Hystrix
Sentinel的功能和Hystrix非常相似,但由于晚于Hystrix出現,所以功能更加全面,使用非常便捷
| Hystrix | 需要程序人員自己搭建監控平臺并通過Turbine來收集監控信息 | 沒有一個完整的服務管理平臺給我們提供更細粒度的配置,比如:流控、速率控制、服務熔斷、服務降級的配置等,所有的降級熔斷都需要提前在yaml里設計好,對于業務的突發式的變更使用上很不靈活 |
| Sentinel | 單獨一個組件獨立出來和業務沒有關聯 | 統一d額界面化配置,更細粒度更靈活的處理相關設置 |
2. Sentinel應用啟動
直接去github上下載一個控制臺服務端
Sentinel核心功能:服務雪崩、服務降級、服務熔斷、服務限流這幾個方面內容
下載完成后,可以直接啟動
java -jar sentinel-dashboard-1.7.2.jar nohup java -jar sentinel-dashboard-1.7.2.jar & localhost:8080 # 直接sentinel用戶名密碼訪問即可3. 服務集成Sentinel
父模塊導入一個springcloud alibaba的總依賴
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.1.RELEASE</version><type>pom</type><scope>import</scope></dependency>具體調用的module里加入sentinel的依賴
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>yaml里需要增加sentinel的部分
server:port: 8081 spring:application:name: nacos-providercloud:nacos:discovery:server-addr: 127.0.0.1:8848config:server-addr: 127.0.0.1:8848file-extension: yamlsentinel:transport:dashboard: 127.0.0.1:8080 #將服務托管到具體的sentinel中啟動類和nacos的一樣
package com.icodingedu.springcloud;import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication @EnableDiscoveryClient public class NacosProviderApplication {public static void main(String[] args) {new SpringApplicationBuilder(NacosProviderApplication.class).web(WebApplicationType.SERVLET).run(args);} }controller實現沒有特殊要求
package com.icodingedu.springcloud.controller;import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;@RestController @Slf4j //配置支持動態更新 @RefreshScope public class ProviderController {@Value("${config.info}")private String config;@Value("${server.port}")private String server_port;@GetMapping("/say")public String sayhello(){return "this is nacos : "+server_port+" config : "+config;}@GetMapping("testa")public String testA(){return "this is test A";}@GetMapping("testb")public String testB(){return "this is test B";} }項目啟動后進入sentinel中查看沒有任何內容,因為sentinel采用的是懶加載機制,需要將注冊到sentinel中的服務進行一下調用,調用后才會展示到dashboard中
注意:訪問了哪個接口,哪個接口才會出現在sentinel中
4. 流控設置
分布式流量控制
- google guava來進行單機的流量控制
- Nginx來進行網關層的流量控制
- Redis來進行中間件層面的流量控制
- 第三方組件進行流量控制:Sentinel
SpringCloud Netflix全家桶,流量控制:Gateway進行流量控制,基于Redis進行的令牌桶的機制,這個策略是提前設置好的,如果流量比較大,出現和預期不符的情況,需要修改Gateway的流控規則來進行匹配,比較不靈活
4.1. QPS限流
將服務注冊到Sentinel后可以對相應的接口進行流控設置
這個流控是動態配置直接生效的,不需要其他代碼層面的流控規則,不需要重啟服務,sentinel直接生效就能進行流量控制,返回的信息是sentinel默認提供的(Blocked by Sentinel (flow limiting)),如果我們要修改這個提示如何修改呢?
4.2. 線程限流
如果我們在閾值類型設置上將QPS更改成線程數,單機閾值還是1
配置完畢后快速點擊接口服務是不會出現流控的提示的
線程是指這個接口只有一個線程來處理請求,處理完一個就處理下一個,如果一個沒有處理完來了另外一個就會拋出系統默認的錯誤提示Blocked by Sentinel (flow limiting)
4.3. 流控的關聯模式
相當于別人犯錯自己買單,當B接口超過閾值后,將對A進行限流
對誰限流,就在誰的簇點鏈路上進行流控創建
可以使用postman的方式訪問testb,然后去看testa是否被限流了
Run testb就可以去測試看testa是否被限流了
在業務場景上,比如訪問系統某個連接過于頻繁,支付訪問過于頻繁,就將前一個環節的接口進行限流
4.4. Warm up
流控預熱
我們可以先看一下官網
https://github.com/alibaba/Sentinel/wiki/限流---冷啟動默認coldFactor為3,即請求QPS從threshold / 3開始,經過預熱時長逐漸升至設定的QPS閾值
threshold:這就是配置的閾值
coldFactor:默認值可以在代碼里找到
直接配置進行測試
這個配置相當于接口在5秒的預熱內是從10/3個訪問閾值開始,超過后就會限流報錯,5秒后閾值則恢復到10,預熱的方式就是讓系統的某個時點前先適應相應的流量壓力,不至于一下子流量進入就把系統壓垮
4.5. 限流隊列
相當于進入處理的業務在沒有獲得資源時先進入隊列等待,超過等待時長還未處理則報錯,如果沒有超過則獲取到資源進行響應
這里是等待200ms,但QPS是1,表示1秒允許通過一個請求,所以如果點擊過快則會出現限流錯誤
可以將超時時間設置的長一些,設置等待時間超過QPS則會拿到數據資源,但等待時長并不會以設置的時長來進行,只會等待拿到資源為止的時間
實際實現的是漏桶算法
5. 熔斷降級
先看一下官方說明
https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7Sentinel 提供以下幾種熔斷策略:
- 慢調用比例 (SLOW_REQUEST_RATIO):選擇以慢調用比例作為閾值,需要設置允許的慢調用 RT(即最大的響應時間),請求的響應時間大于該值則統計為慢調用。當單位統計時長(statIntervalMs)內請求數目大于設置的最小請求數目,并且慢調用的比例大于閾值,則接下來的熔斷時長內請求會自動被熔斷。經過熔斷時長后熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求響應時間小于設置的慢調用 RT 則結束熔斷,若大于設置的慢調用 RT 則會再次被熔斷。
- 異常比例 (ERROR_RATIO):當單位統計時長(statIntervalMs)內請求數目大于設置的最小請求數目,并且異常的比例大于閾值,則接下來的熔斷時長內請求會自動被熔斷。經過熔斷時長后熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求成功完成(沒有錯誤)則結束熔斷,否則會再次被熔斷。異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%。
- 異常數 (ERROR_COUNT):當單位統計時長內的異常數目超過閾值之后會自動進行熔斷。經過熔斷時長后熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求成功完成(沒有錯誤)則結束熔斷,否則會再次被熔斷。
5.1. RT降級
我們先構造一個controller
@GetMapping("testc")public String testC(){try{Thread.sleep(1000);}catch (Exception ex){ex.printStackTrace();}return "this is test C";}在簇點鏈路上選擇資源的降級設置
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2Z0BpCmn-1640930500968)(Alibaba Sentinel 流控衛兵.assets/image-20201104212717790.png)]
這個相當于在1秒內N個請求,每個請求的平均響應時間超過200ms,在下一個時間窗口10秒內所有的請求全部返回系統的降級提示結果
用postman調用10次,每次300ms,然后在瀏覽器上再次訪問就會進入10秒內調用返回系統默認的異常信息:Blocked by Sentinel (flow limiting)
5.2. 異常比例
當1秒內接口的錯誤請求超過設置的異常比例,就會在下個時間窗口內進行降級,返回默認的結果
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FDlPkkoE-1640930500968)(Alibaba Sentinel 流控衛兵.assets/image-20201104213541496.png)]
以上配置的意思是在1秒內,請求錯誤占所有請求的80%時,在下一個10秒內接口直接降級
5.3. 異常數
這個類似于異常比例,只是將比例更改為更具體的錯誤數字,驗證錯誤此時的時間由1秒變更為1分鐘
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-6dqEETcT-1640930500969)(Alibaba Sentinel 流控衛兵.assets/image-20201104214248618.png)]
6. 熱點參數限流
同樣先看官網說明
https://github.com/alibaba/Sentinel/wiki/熱點參數限流何為熱點?熱點即經常訪問的數據。很多時候我們希望統計某個熱點數據中訪問頻次最高的 Top K 數據,并對其訪問進行限制。比如:
- 商品 ID 為參數,統計一段時間內最常購買的商品 ID 并進行限制
- 用戶 ID 為參數,針對一段時間內頻繁訪問的用戶 ID 進行限制
熱點參數限流會統計傳入參數中的熱點參數,并根據配置的限流閾值與模式,對包含熱點參數的資源調用進行限流。熱點參數限流可以看做是一種特殊的流量控制,僅對包含熱點參數的資源調用生效。
6.1. 基本配置
我們先寫一個測試的實現
@GetMapping("testhot")@SentinelResource(value = "hotkey",blockHandler = "hotkeyFallback")public String testHotKey(@RequestParam(value = "p1",required = false) String p1,@RequestParam(value = "p2",required = false) String p2){return "返回testHotKey信息";}//這就是自定義的fallbackpublic String hotkeyFallback(String p1,String p2,BlockException exception){return "這時hotkeyFallback方法返回";}下面是sentinel的配置
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-A4KXsztD-1640930500970)(Alibaba Sentinel 流控衛兵.assets/image-20201104220126116.png)]
注意這里參數索引的意思是你有多個參數,以哪個參數為熱點,只有連接中包含了那個參數,這個時候限流才生效,不包含指定參數限流規則是不生效的,注意參數索引是方法簽名里寫的順序,從0開始而非調用時填寫的順序
6.2. 高級配置
參數例外項的配置
參數中的某個值需要更加個性化的限流配置,如下圖所示
新增加了一個例外項配置,當參數順序為0的參數值等于5的時候,1秒內的閾值時20,除了5以外還是1
這個功能可以實現對某個vip用戶開放并發訪問的權限和能力
如果業務代碼里出現異常,但是訪問頻次依舊超過了閾值,這個時候還是會調用sentinel的fallback方法,sentinel早于業務代碼實現
7. 系統規則
系統保護規則是從應用級別的入口流量進行控制,從單臺機器的 load、CPU 使用率、平均 RT、入口 QPS 和并發線程數等幾個維度監控應用指標,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。
系統保護規則是應用整體維度的,而不是資源維度的,并且僅對入口流量生效。入口流量指的是進入應用的流量(EntryType.IN),比如 Web 服務或 Dubbo 服務端接收的請求,都屬于入口流量。
系統規則支持以下的模式:
- Load 自適應(僅對 Linux/Unix-like 機器生效):系統的 load1 作為啟發指標,進行自適應系統保護。當系統 load1 超過設定的啟發值,且系統當前的并發線程數超過估算的系統容量時才會觸發系統保護(BBR 階段)。系統容量由系統的 maxQps * minRt 估算得出。設定參考值一般是 CPU cores * 2.5。
- CPU usage(1.5.0+ 版本):當系統 CPU 使用率超過閾值即觸發系統保護(取值范圍 0.0-1.0),比較靈敏。
- 平均 RT:當單臺機器上所有入口流量的平均 RT 達到閾值即觸發系統保護,單位是毫秒。
- 并發線程數:當單臺機器上所有入口流量的并發線程數達到閾值即觸發系統保護。
- 入口 QPS:當單臺機器上所有入口流量的 QPS 達到閾值即觸發系統保護。
8. @SentinelResource
使用@SnetinelResource注解可以指定資源信息進行訪問,并設置本地限流的訪問方法,如果不設置本地的限流方法就會使用系統默認的限流返回,這里會有以下幾個問題:
- 系統默認的返回提示不能體現業務要求
- 自定的限流異常處理邏輯和業務代碼耦合在一起不能直觀的體現業務功能
- 每個業務功能都提供異常業務處理方法,代碼會膨脹加劇
- 全局統計處理沒有體現
8.1. 自定義blockhandler
我們實現一個自定義的本地統一異常處理存根
package com.icodingedu.springcloud.service;import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.stereotype.Service;@Service public class MyBlockHandler {//方法必須加上static,不然調用會報錯public static String hotkeyFallback(String p1, String p2, BlockException exception){return "這是hotkeyFallback方法返回";} }業務調用的地方要顯示調用這個類
@GetMapping("testhot")@SentinelResource(value = "hotkey",blockHandlerClass = MyBlockHandler.class,blockHandler = "hotkeyFallback")public String testHotKey(@RequestParam(value = "p1",required = false) String p1,@RequestParam(value = "p2",required = false) String p2){int i = 1/0;return "返回testHotKey信息";}8.2. 自定義fallback
可以在方法上指定fallback方法,讓程序知道在出現異常時調用什么降級內容
@GetMapping("testa")@SentinelResource(value="serviceA",fallback = "serviceFall")public String testA(Integer req){return "this is test A";}public String serviceFall(Integer req){return "service fallback : "+req;}8.3. fallback異常忽略
@GetMapping("testa")@SentinelResource(value="serviceA",fallback = "serviceFall",exceptionsToIgnore = {ArithmeticException.class})public String testA(Integer req){if(req==1){int i=1/0;}return "this is test A";}public String serviceFall(Integer req){return "service fallback : "+req;}忽略異常后,如果出現對應忽略的異常,系統正常拋錯,不會進入fallback方法
9. Sentinel和Feign的集成
在consumer調用端要引入POM依賴
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency></dependencies>consumer調用端的yaml配置
server:port: 8091 spring:application:name: nacos-consumercloud: nacos: discovery:server-addr: 127.0.0.1:8848sentinel: transport:dashboard: 127.0.0.1:8080 feign:sentinel:enabled: true management:endpoints:web:exposure:include: '*'feign進行遠程調用,在接口上增加fallback
package com.icodingedu.springcloud.service;import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping;@FeignClient(value = "nacos-provider",fallback = FeignServiceImpl.class) public interface FeignService {@GetMapping("/say")public String sayhello(); }本地fallback實現
package com.icodingedu.springcloud.service;import org.springframework.stereotype.Service;@Service public class FeignServiceImpl implements FeignService {@Overridepublic String sayhello() {return "Feign Local Service";} }10. Sentinel規則持久化
問題提出:當注冊到sentinel中的服務一旦重啟,所有的規則都將失效了,如果規則比較少還可以,一旦多了的話重啟后失效就比較崩潰了,所以需要將規則進行持久化
我們結合Nacos將配置持久化到Nacos中,當然也可以持久化到數據庫,Redis等媒介中
需要持久化流控規則的項目需要加入以下POM依賴
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency>在yaml里配置sentinel關聯Nacos
server:port: 8081 spring:application:name: nacos-providercloud:nacos:discovery:server-addr: 127.0.0.1:8848config:server-addr: 127.0.0.1:8848file-extension: yamlsentinel:transport:dashboard: 127.0.0.1:8080 #將服務托管到具體的sentinel中datasource:ds1:nacos:server-addr: localhost:8848dataId: provider-sentinel-servicegroupId: DEFAULT_GROUPdata-type: jsonrule-type: flow在Nacos中創建DataId為:provider-sentinel-service,且數據格式為json的配置
[{"resource": "/say","limitApp": "default","grade": 1,"count": 1,"strategy": 0,"controlBehavior": 0,"clusterMode": false} ]# resource:資源名稱 # limitApp:來源應用 # grade:閾值類型,0-線程數,1-QPS # count:單機閾值 # strategy:流控模式,0-快速失敗,1-Warm Up,2-排隊等待 # controlBehavior:流控模式,0-直接,1-關聯,2-鏈路 # clusterMode:是否集群總結
以上是生活随笔為你收集整理的可视化界面 Sentinel 流控卫兵 限流 熔断 系统保护的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 四阶段:第24周 微服务下Sentine
- 下一篇: java信息管理系统总结_java实现科