天天看點

Sentinel落地與應用1.Sentinel 介紹2.如何使用Sentinel3.Feign 支援4.Spring Cloud Gateway 支援

Sentinel落地與應用1.Sentinel 介紹2.如何使用Sentinel3.Feign 支援4.Spring Cloud Gateway 支援

1.Sentinel 介紹

随着微服務的流行,服務和服務之間的穩定性變得越來越重要。

Sentinel

以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個次元保護服務的穩定性。

具有以下特征:

  • 豐富的應用場景: Sentinel 承接了阿裡巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、消息削峰填谷、實時熔斷下遊不可用應用等。
  • 完備的實時監控: Sentinel 同時提供實時的監控功能。您可以在控制台中看到接入應用的單台機器秒級資料,甚至 500 台以下規模的叢集的彙總運作情況。
  • 廣泛的開源生态: Sentinel 提供開箱即用的與其它開源架構/庫的整合子產品,例如與 Spring Cloud、Dubbo、gRPC 的整合。您隻需要引入相應的依賴并進行簡單的配置即可快速地接入 Sentinel。
  • 完善的 SPI 擴充點: Sentinel 提供簡單易用、完善的 SPI 擴充點。您可以通過實作擴充點,快速的定制邏輯。例如定制規則管理、适配資料源等。

白話來講,作用就是當大量請求怼過來時,你可以設定接收多少請求,其餘的都會傳回 如通路人數過多等資訊(請參考雙11秒殺你大多數參與的結果),這樣保證伺服器不被壓垮,保證了大部分的使用者體驗,同時被熔斷的請求不也會莫名的顯示各種不明是以的報錯或者是直接白頁,體驗更加友好。

2.如何使用Sentinel

1.下載下傳安裝

官網提供打好的jar包直接下載下傳即可.

位址:

github.com/alibaba/Sen…

或者下載下傳源碼,自己打包。

mvn clean package
複制代碼      

會在Sentinel-master\sentinel-dashboard\target下生成。

2.啟動

Sentinel控制台是一個标準的Spring Boot應用,以Spring Boot的方式運作jar包即可。

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
複制代碼      

3.@SentinelResource 注解(使用feign調用可以省略)

埋點功能,在調用接口時,如果發生限流或者是異常,那麼會抛出blockHandler/fallback指定的異常資訊。

注意:注解方式埋點不支援 private 方法。

@SentinelResource用于定義資源,并提供可選的異常處理和 fallback 配置項。@SentinelResource注解包含以下屬性:

  • value:資源名稱,必需項(不能為空)
  • entryType:entry 類型,可選項(預設為 EntryType.OUT)
  • blockHandler / blockHandlerClass: blockHandler對應處理BlockException的函數名稱,可選項。blockHandler 函數通路範圍需要是public,傳回類型需要與原方法相比對,參數類型需要和原方法相比對并且最後加一個額外的參數,類型為BlockException。blockHandler 函數預設需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定blockHandlerClass為對應的類的class對象,注意對應的函數必需為 static 函數,否則無法解析。
  • fallback / fallbackClass:fallback 函數名稱,可選項,用于在抛出異常的時候提供 fallback 處理邏輯。fallback 函數可以針對所有類型的異常(除了exceptionsToIgnore裡面排除掉的異常類型)進行處理。fallback 函數簽名和位置要求:
    • 傳回值類型必須與原函數傳回值類型一緻;
    • 方法參數清單需要和原函數一緻,或者可以額外多一個Throwable類型的參數用于接收對應的異常。
    • fallback 函數預設需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定fallbackClass為對應的類的class對象,注意對應的函數必需為 static 函數,否則無法解析。
  • defaultFallback(since 1.6.0):預設的 fallback 函數名稱,可選項,通常用于通用的 fallback 邏輯(即可以用于很多服務或方法)。預設 fallback 函數可以針對所有類型的異常(除了 exceptionsToIgnore 裡面排除掉的異常類型)進行處理。若同時配置了 fallback 和 defaultFallback,則隻有 fallback 會生效。defaultFallback 函數簽名要求:
    • 方法參數清單需要為空,或者可以額外多一個 Throwable 類型的參數用于接收對應的異常。
    • defaultFallback 函數預設需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 fallbackClass 為對應的類的 Class 對象,注意對應的函數必需為 static 函數,否則無法解析。
  • exceptionsToIgnore(since 1.6.0):用于指定哪些異常被排除掉,不會計入異常統計中,也不會進入 fallback 邏輯中,而是會原樣抛出。

1.8.0 版本開始,defaultFallback 支援在類級别進行配置。

注:1.6.0 之前的版本,fallback 函數隻針對降級異常(DegradeException)進行處理,不能針對業務異常進行處理。

特别地,若 blockHandler和fallback都進行了配置,則被限流降級而抛出 BlockException 時隻會進入 blockHandler 處理邏輯。若未配置 blockHandler、fallback 和 defaultFallback,則被限流降級時會将 BlockException 直接抛出(若方法本身未定義 throws BlockException 則會被 JVM 包裝一層 UndeclaredThrowableException)。

示例:

public class TestService {
 
    // 原函數
    @SentinelResource(value = "hello", blockHandler = "exceptionHandler", fallback = "helloFallback")
    public String hello(long s) {
        return String.format("Hello at %d", s);
    }
    
    // Fallback 函數,函數簽名與原函數一緻或加一個 Throwable 類型的參數.
    public String helloFallback(long s) {
        return String.format("Halooooo %d", s);
    }
 
    // Block 異常處理函數,參數最後多一個 BlockException,其餘與原函數一緻.
    public String exceptionHandler(long s, BlockException ex) {
        // Do some log here.
        ex.printStackTrace();
        return "Oops, error occurred at " + s;
    }
 
    // 這裡單獨示範 blockHandlerClass 的配置.
    // 對應的 `handleException` 函數需要位于 `ExceptionUtil` 類中,并且必須為 public static 函數.
    @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})
    public void test() {
        System.out.println("Test");
    }
}
複制代碼      

4.springboot整合

如果要在您的項目中引入 Sentinel,使用 group ID 為 com.alibaba.cloud 和 artifact ID 為 spring-cloud-starter-alibaba-sentinel 的 starter。

1.修改pom.xml

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
複制代碼      

2.修改application.yml

spring:
  cloud:
    sentinel:
      transport:
        port: 8719 #如果是多個服務 端口不能相同
        dashboard: ip:8080
複制代碼      

spring.cloud.sentinel.transport.port是本地啟的端口,與dashboard進行資料互動。官方文檔是這樣寫的:這裡的 spring.cloud.sentinel.transport.port 端口配置會在應用對應的機器上啟動一個 Http Server,該 Server 會與 Sentinel 控制台做互動。比如 Sentinel 控制台添加了一個限流規則,會把規則資料 push 給這個 Http Server 接收,Http Server 再将規則注冊到 Sentinel 中。

注意transport:port: 8719 這個端口不能多次占用,比如果一個項目制定的為8719 那麼同伺服器的任何項目都不能在使用8719了

3.驗證

通路ip:8080賬号/密碼,出現以下頁面即可。

Sentinel落地與應用1.Sentinel 介紹2.如何使用Sentinel3.Feign 支援4.Spring Cloud Gateway 支援
注意:當通路一次接口之後 才能在左面出現服務選項!!

3.Feign 支援

Sentinel 适配了 Feign 元件。如果想使用,除了引入 spring-cloud-starter-alibaba-sentinel 的依賴外還需要 2 個步驟:

  1. 配置檔案打開 Sentinel 對 Feign 的支援:feign.sentinel.enabled=true
  2. 加入 spring-cloud-starter-openfeign 依賴使 Sentinel starter 中的自動化配置類生效:
如果不開啟,将不能實作熔斷,會直接抛出異常!

1.修改yml檔案

feign:
  sentinel:
    enabled: true
複制代碼      

2.示例

這是一個 FeignClient 的簡單使用示例:

@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
    @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
    String echo(@PathVariable("str") String str);
}
 
class FeignConfiguration {
    @Bean
    public EchoServiceFallback echoServiceFallback() {
        return new EchoServiceFallback();
    }
}
 
class EchoServiceFallback implements EchoService {
    @Override
    public String echo(@PathVariable("str") String str) {
        return "echo fallback";
    }
}
複制代碼      

4.Spring Cloud Gateway 支援

若想跟 Sentinel Starter 配合使用,需要加上 spring-cloud-alibaba-sentinel-gateway 依賴,同時需要添加 spring-cloud-starter-gateway 依賴來讓 spring-cloud-alibaba-sentinel-gateway 子產品裡的 Spring Cloud Gateway 自動化配置類生效:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
 
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
 
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>