SpringCloud——Sentinel入門

charon_ni發表於2020-12-30

隨著微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。

一、下載執行啟動

1.1安裝

官網下載: https://github.com/alibaba/Sentinel/releases
java -jar 方式執行 安裝下載檔案。瀏覽器輸入http://localhost:8080即可進入登入頁面。賬號密碼均為sentinel。

1.2maven引入

	<dependencies>
        <!--自定義的jar包-->
        <dependency>
            <groupId>com.charon</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--SpringCloud ailibaba nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel-datasource-nacos 後續做持久化用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- SpringBoot整合Web元件+actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--日常通用jar包配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

1.3配置檔案

server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服務註冊中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        #預設8719埠,假如被佔用會自動從8719開始依次+1掃描,直至找到未被佔用的埠
        port: 8719
      #持久化進行nacos
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

management:
  endpoints:
    web:
      exposure:
        include: '*'
        
# 啟用Sentinel對Feign的支援
feign:
  sentinel:
    enabled: true

只有監控到rest請求才會出現以下介面(這邊採用懶載入,並非僅監聽專案就可,需要一次請求進入
在這裡插入圖片描述

二、sentinel控制檯介紹

2.1流控規則

在這裡插入圖片描述
①:資源名:唯一名稱,預設請求路徑。
②:針對來源: Sentinel可以針對呼叫者進行限流,填寫微服務名,預設default(不區分來源)·
③:閾值型別/單機閾值
QPS(每秒鐘的請求數量)︰當呼叫該api的QPS達到閾值的時候,進行限流。
執行緒數:當呼叫該api的執行緒數達到閾值的時候,進行限流。
④:是否叢集:不需要叢集
⑤:流控模式:
直接:api達到限流條件時,直接限流。
關聯:當關聯的資源達到閾值時,就限流自己。
鏈路:只記錄指定鏈路上的流量(指定資源從入口資源進來的流量,如果達到閾值,就進行限流)【api級別的針對來源】。
⑥:流控效果:
快速失敗:直接失敗,拋異常。
Warm Up:根據codeFactor (冷載入因子,預設3)的值,從閾值/codeFactor,經過預熱時長,才達到設定的QPS閾值。
排隊等待:勻速排隊,讓請求以勻速的速度通過,閾值型別必須設定為QPS,否則無效。

2.2降級規則

在這裡插入圖片描述
RT(平均響應時間 秒級):平均響應時間超出閾值且在時間視窗內通過的請求>=5,兩個條件同時滿足後觸發降級視窗期過後關閉斷路器。
RT最大4900(更大的需要通過-Dcsp.sentinel.statistic.max.rt=XXXX才能生效)
②:異常比例:(為滿足要求直接報錯,滿足要求請求提示出友好頁面Blocked by Sentinel (flow limiting))QPS >=5且異常比例(秒級統計)超過閾值時,觸發降級;時間視窗結束後,關閉降級。
③:異常數:當資源近一分鐘的異常數目超過閾值之後進行熔斷。注意統計時間視窗是分鐘級別的,若timeout小於60s,則結束熔斷狀態後仍可能在進入熔斷。

2.3系統規則(針對於整個系統而言)

在這裡插入圖片描述
①:Load自適應(僅對 Linux/Unix-like機器生效):系統的 load1作為啟發指標,進行自適應系統保護。當系統load1超過設定的啟發值,且系統當前的併發執行緒數超過估算的系統容量時才會觸發系統保護(BBR階段)。系統容量由系統的maxOps * minRt估算得出。設定參考值一般是CPu cores * 2.5。
②:CPU usage (1.5.0+版本)︰當系統CPU使用率超過閾值即觸發系統保護(取值範圍0.0-1.0) , 比較靈敏。
③:平均RT:當單臺機器上所有入口流量的平均RT達到閾值即觸發系統保護,單位是毫秒。
④:併發執行緒數:當單臺機器上所有入口流量的併發執行緒數達到閾值即觸發系統保護。
⑤:入口QPS:當單臺機器上所有入口流量的QPS達到閾值即觸發系統保護。

2.4熱點規則

在這裡插入圖片描述

 /**
     * 熱點規則 報錯不會執行blockHandler兜底方法;blockHandler只管控控制檯配置
     * @param p1 引數1
     * @param p2 引數2
     * @return
     */
    @GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                             @RequestParam(value = "p2",required = false) String p2) {
        //int age = 10/0;
        return "------testHotKey";
    }

    /**
     * 自定義返回的友好提示頁面
     * @param p1 引數1
     * @param p2 引數2
     * @param exception 異常資訊
     * @return
     */
    public String deal_testHotKey (String p1, String p2, BlockException exception) {
        //sentinel系統預設的提示:Blocked by Sentinel (flow limiting)
        return "------deal_testHotKey-------";
    }

2.5Sentinel介紹

1.Sentinel熔斷降級會在呼叫鏈路中某個資源出現不穩定狀態時(例如呼叫超時或異常比例升高),對這個資源的呼叫進行限制,讓請求快速失敗,避免影響到其它的資源而導致級聯錯誤。當資源被降級後,在接下來的降級時間視窗之內,對該資源的呼叫都自動熔斷(預設行為是丟擲DegradeException)
2.Sentinel的斷路器是沒有半開狀態的:半開的狀態系統自動去檢測是否請求有異常,沒有異常就關閉斷路器恢復使用,有異常則繼續開啟斷路器不可用。
3.Sentinel主要有三個核心Api:①:SphU定義資源②:Tracer定義統計③:ContextUtil定義了上下文

2.6SentinelResource配置

1.限流模式僅支援QPS
2.SentinelResource配置限流:

@RestController
@Slf4j
public class RateLimitController {

    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandler = "handleException")
    public CommonResult byResource() {
        return new CommonResult(200,"按資源名稱限流測試OK",new Payment(2020L,"serial001"));
    }

    public CommonResult handleException(BlockException exception) {
        return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服務不可用");
    }

    @GetMapping("/rateLimit/byUrl")
    @SentinelResource(value = "byUrl")
    public CommonResult byUrl() {
        return new CommonResult(200,"按url限流測試OK",new Payment(2020L,"serial002"));
    }


    @GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",
    blockHandlerClass = CustomerBlockHandler.class,
    blockHandler = "handlerException2")
    public CommonResult customerBlockHandler() {
        return new CommonResult(200,"按客戶自定義",new Payment(2020L,"serial003"));
    }
}
public class CustomerBlockHandler {

    public static CommonResult handlerException(BlockException exception) {
        return new CommonResult(4444,"按客戶自定義,global handlerException----1");
    }

    public static CommonResult handlerException2(BlockException exception)
    {
        return new CommonResult(4444,"按客戶自定義,global handlerException----2");
    }

}

3.@SentinelResource處理是控制檯的違規情況,有blockHandler方法配置的兜底處理,如果是java執行是異常是不予管理。註解是不支援private方法。

@RequestMapping("/consumer/fallback/{id}")
   // @SentinelResource(value = "fallback")
   // @SentinelResource(value = "fallback",fallback = "handlerFallback")
    //@SentinelResource(value = "fallback",blockHandler = "blockHandler")
    @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
                        exceptionsToIgnore = {IllegalArgumentException.class,IndexOutOfBoundsException.class})
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id, CommonResult.class,id);
        if (id == 4) {
            throw new IllegalArgumentException ("IllegalArgumentException,非法引數異常....");
        }else if (result.getData() == null) {
            throw new NullPointerException ("NullPointerException,該ID沒有對應記錄,空指標異常");
        }
        return result;
    }

①:什麼都沒配置只有value:對於異常和限流都無效,該什麼樣子就是什麼樣子。
②:只配置fallback:無法進行限流,但是可以對於異常資訊進行捕捉進而執行兜底方法。
③:只配置blockHandler :只可以對於控制檯配置進行處理,但是對於異常資訊無法處理。遇到異常就將異常資訊返回頁面。
④:即配置fallback又配置blockHandler:既可以對於異常進行捕捉進而執行兜底方法又可以對於控制檯配置管控。如果被限流降級而丟擲BlockException時只會進入blockHandler處理邏輯。
⑤:配置exceptionsToIgnore:對於配置異常的出現不走兜底方法,進而直接返回頁面錯誤資訊。

2.7Sentinel持久化

2.7.1配置檔案新增(如上面配置檔案)

 #持久化進行nacos
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
# 啟用Sentinel對Feign的支援
feign:
  sentinel:
    enabled: true

2.7.2nacos配置

在新增配置時候選擇json格式,配置完如下圖所示:
在這裡插入圖片描述
json配置檔案內容解析:
在這裡插入圖片描述
配置完畢後當我們重新啟動專案,我們所配置的規則就不會消失,再讓我們重新配置(一定要先進行一次rest請求)。此時存在一個問題如果配置規則過多我們需要每一個進行填寫,還是會耗費大量時間。如果有人看到本文並且有好的解決方案可在評論中附上鍊接,萬分感謝。

相關文章