1. 程式人生 > 其它 >sentinel基礎概念及使用

sentinel基礎概念及使用

點贊再看,養成習慣,微信搜尋「小大白日誌」關注這個搬磚人。

文章不定期同步公眾號,還有各種一線大廠面試原題、我的學習系列筆記。

什麼是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,如果文章哪裡有錯誤或不足,歡迎各位留言。

創作不易,各位的「三連」是二少創作的最大動力!我們下期見!