sentinel基礎概念及使用
阿新 • • 發佈:2021-07-18
點贊再看,養成習慣,微信搜尋「小大白日誌」關注這個搬磚人。
文章不定期同步公眾號,還有各種一線大廠面試原題、我的學習系列筆記。
什麼是sentinel
- sentinel是Spring Cloud Alibaba的一個重要元件,類似於spring clound的hystrix,與hystrix-dashboard控制檯一樣,sentinel-dashboard控制檯可以提供對流量的實時監控、線上維護流量規則、熔斷規則,前提是微服務整合了sentinel
- 對比hystrix
Sentinel | Hystrix | |
---|---|---|
隔離策略 | 訊號量隔離 | 執行緒池隔離/訊號量隔離 |
熔斷降級策略 | 基於響應時間或失敗比率 | 執行緒池隔離/ 基於響應時間或失敗比率 |
實時指標實現 | 滑動視窗 | 滑動視窗(基於 RxJava) |
規則配置 | 支援多種資料來源 | 支援多種資料來源 |
擴充套件性 | 多個擴充套件點 | 外掛的形式 |
基於註解的支援 | 支援 | 支援 |
限流 | 基於 QPS,支援基於呼叫關係的限流 | 有限的支援 |
流量整形 | 支援慢啟動、勻速器模式 | 不支援 |
系統負載保護 | 支援 | 不支援 |
控制檯 | 開箱即用,可配置規則、檢視秒級監控、機器發現等 | 不完善 |
常見框架的適配 | Servlet、Spring Cloud、Dubbo、gRPC 等 | Servlet、Spring Cloud Netflix |
hystrix官方已停止更新,而sentinel則保持著開源
基礎概念
- Resource:資源resource可以是程式碼塊、方法(普通方法、介面)等,把它們定義為資源後,再定義限流規則,就可以結合sentinel使用了
- Slot插槽:sentinel中定義了7種slot插槽,sentinel正是通過各個插槽間的固定呼叫順序來實現限流的,因為後面的插槽可能依賴於前面插槽的計算結果
- Entry:是否通過限流的憑證,sentinel有三種形式來定義資源
- 呼叫SphU.entry("資源")來定義資源:定義成功則返回一個Entry物件,否則丟擲異常以拒絕往下執行限流程式碼,代表此資源已被定義,需要執行其他處理程式碼,不管是否成功定義資源最後都要執行entry.exit()退出資源
- 呼叫SphO.entry("資源")來定義資源:返回true表示定義成功,若定義資源失敗則返回false以拒絕往下執行限流程式碼,需要執行其他處理程式碼,不管是否成功定義資源最後都要執行SphO.exit()退出資源呼叫
- 註解的方式定義資源:上面兩種方式對程式碼侵入性很高,可用@SentinelResource註解的方式作用於方法上,並配置blockHandler指定限流處理方式
- Node節點:DefaultNode=鏈路節點,可統計呼叫鏈路上某個資源的資料;ClusterNode=簇節點,可統計某個資源的全域性資料;StatisticNode=基礎節點,其資料結構有秒級/分鐘級別的滑動視窗結構;EntranceNode=入口節點,包含一些入口資料
- Context:上下文,ThreadLocal傳遞,包含一次鏈路呼叫的所有資訊,如鏈路節點DefaultNode,入口節點EntranceNode
使用sentinel:定義限流規則及定義資源
- 引入依賴
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.7.1</version>
</dependency>
- 定義規則及定義資源
規則是要作用於資源上的,下面先定義規則,再用【SphU.entry()】或【SphO.entry()】或註解的形式定義資源:
public class demo {
public static void main(String[] args) {
// 定義規則
initFlowRules();
//用SphU.entry()的形式定義資源
while (true) {
try (Entry entry = SphU.entry("myResource")) {//與規則定義中的rule.setResource("myResource")一致
// 被保護的業務邏輯...
System.out.println("業務資源訪問成功!");
} catch (BlockException ex) {
// 處理被流控的邏輯:限流或降級...
System.out.println("資源訪問失敗!!!");
} finally {
if (entry != null) {
entry.exit();//必須退出資源呼叫
}
}
}
//用SphO.entry()的形式定義資源
while (true) {
if(SphO.entry("myResource")){//與規則定義中的rule.setResource("myResource")一致
try{
// 被保護的業務邏輯...
System.out.println("業務資源訪問成功!");
} catch (BlockException ex) {
// 處理被流控的邏輯:限流或降級...
System.out.println("資源訪問失敗!!!");
}finally{
SphO.exit();//必須退出資源呼叫
}
}
}
//上面兩種方式對程式碼侵入性很高,可用註解的方式定義資源
while(true){
getUserById("111");
}
}
//定義規則
private static void initFlowRules(){
List<FlowRule> rules = new ArrayList<>();// 儲存規則 FlowRule
FlowRule rule = new FlowRule();
rule.setResource("myResource"); // 指定限流規則作用於哪個資源上,資源名為字串,可為任意有標識意義的方法名/介面名/其他字串,此處資源名為"myResource"
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 限流型別為QPS模式:限制QPS
rule.setCount(10); // QPS不得超出10
rule.setLimitApp("default"); // 針對的呼叫來源,default代表不區分來源
rules.add(rule);
FlowRuleManager.loadRules(rules);// 載入規則
}
//定義"myResource"資源,並設定違背sentinel流控規則時的處理方法handlerException()
@SentinelResource(value="myResource",blockHandler="handlerException")
public User getUserById(String id){
return new User("資料庫使用者");
}
//注意:此處理方法的引數必須和定義資源的方法getUserById引數一致()同時加上【BlockException exception】引數
public User handlerException(String id,BlockException exception){
return new User("流控使用者");
}
}
Entry entry = null;
try {
entry = SphU.entry("myResource"); //此處說明資源
// 被保護的業務邏輯
...
} catch (BlockException e1) {
// 資源訪問阻止,被限流或被降級,進行相應的處理操作
...
} finally {
if (entry != null) {
entry.exit();
}
}
單獨啟動sentinel
- 下載sentinel-dashboard-1.6.0.jar包(++連結++),啟動:java -jar
-Dserver.port=8888 sentinel-dashboard-1.6.0.jar
-
訪問localhost:8888登入sentinel-dashboard控制檯,預設使用者名稱/密碼是sentinel/sentinel
可以看到控制檯沒有對任何的微服務進行流量監控 -
專案整合sentinel
- pom.xml引入依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
- 在專案的properties檔案中加入:
spring.clound.sentinel.transport.dashboard=localhost:8888 #設定sentinel控制檯的地址 spring.application.name=myapp #專案名
- 瀏覽器訪問該專案後,再次回到sentinel控制檯,可以看到myapp專案中所有對controller介面的監控,可以在左側“簇點鏈路”新增流控規則,設定每個介面的QPS(每秒允許訪問多少次)
OK,如果文章哪裡有錯誤或不足,歡迎各位留言。
創作不易,各位的「三連」是二少創作的最大動力!我們下期見!