客戶端容錯保護Alibaba Sentinel


18年底Netflix官方宣布Hystrix 已經足夠穩定,不再積極開發 Hystrix,該項目將處於維護模式。就目前來看Hystrix是比較穩定的,並且Hystrix只是停止開發新的版本,並不是完全停止維護,Bug什么的依然會維護的。因此短期內,Hystrix依然是繼續使用的。但從長遠來看,Hystrix總會達到它的生命周期的。

Hystrix的替換方案:Alibaba Sentinel、Resilience4J

  

Sentinel概述:

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

  Sentinel 具有以下特征:
    豐富的應用場景 :Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的范圍)、消息削峰填谷、集群流量控制、實時熔斷下游不可用應用等。
    完備的實時監控 :Sentinel 同時提供實時的監控功能。您可以在控制台中看到接入應用的單台機器秒級數據,甚至 500 台以下規模的集群的匯總運行情況。
    廣泛的開源生態 :Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 SpringCloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴並進行簡單的配置即可快速地接入Sentinel。
    完善的 SPI 擴展點:Sentinel 提供簡單易用、完善的 SPI 擴展接口。您可以通過實現擴展接口來快速地定制邏輯。例如定制規則管理、適配動態數據源等。

  Sentinel 的主要特性:

    

  Sentinel 可以簡單的分為 Sentinel 核心庫和 Dashboard。核心庫不依賴 Dashboard,但是結合Dashboard 可以取得最好的效果。

  使用 Sentinel 來進行熔斷保護,主要分為幾個步驟:

    1. 定義資源
    2. 定義規則
    3. 檢驗規則是否生效

    資源:可以是任何東西,一個服務,服務里的方法,甚至是一段代碼。
    規則:Sentinel 支持以下幾種規則:流量控制規則、熔斷降級規則、系統保護規則、來源訪問控制規則和熱點參數規則。
         Sentinel 的所有規則都可以在內存態中動態地查詢及修改,修改之后立即生效
    先把可能需要保護的資源定義好,之后再配置規則。也可以理解為,只要有了資源,我們就可以在任何時候靈活地定義各種流量控制規則。在編碼的時候,只需要考慮這個代碼是否需要保護,如果需要保護,就將之定義為一個資源。

Sentinel組件:

  管理控制台:
    獲取 Sentinel 控制台 https://github.com/alibaba/Sentinel

    在存放jar包的目錄,使用如下命令啟動控制台:

      java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-x.x.x.jar
      其中 - Dserver.port=8080 用於指定 Sentinel 控制台端口為 8080 。

      在瀏覽器中訪問 http://localhost:8080/ 輸入賬號密碼即可登錄

      從 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登錄功能,默認用戶名和密碼都是 sentinel

      啟動 Sentinel 控制台需要 JDK 版本為 1.8 及以上版本。

    在使用 Sentinel 控制台設置微服務各種訪問規則是存在內存中的,在微服務重啟后規則就會丟失,需要持久化保存

      

       https://www.jianshu.com/p/609961eb6a6e

  將所有的服務交給控制台管理:

    客戶端接入控制台:

      在客戶端(需要管理的微服務)引入坐標

        客戶端需要引入 Transport 模塊來與 Sentinel 控制台進行通信。可以通過 pom.xml 引入 JAR 包:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
</dependency>

      在客戶端配置啟動參數

spring:
  #配置控制台的請求路徑。
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080

    查看機器列表以及健康情況:訪問 http://localhost:8080/ 可看到剛才接入的客戶端

      

      默認情況下 Sentinel 會在客戶端首次調用的時候進行初始化,開始向控制台發送心跳包。也可以配置sentinel.eager=true ,取消Sentinel控制台懶加載。

基於Sentinel的服務保護:

  通用資源保護:

    1.引入依賴

      需要注意SpringCloud-Alibaba與SpringCloud的版本關系

      

       父工程引入 alibaba實現的SpringCloud

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.1.0.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

      子工程(服務消費者)中引入 sentinel

<!-- 當引入此依賴時,前面的客戶端(對應此子工程)的sentinel-transport-simple-http就可以省略了,因為此依賴已包含了它 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

    2.配置熔斷降級方法

/**
 * 訂單控制層
 */
@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;

    /**
     * 通過訂單系統,調用商品服務根據id查詢商品信息
     * @param id
     * @return
     */
    @GetMapping("/buy/{id}")
    @SentinelResource(value="order",blockHandler = "orderBlockHandler",fallback = "orderFallback")
    public Product findById(@PathVariable("id") Long id) {
        return restTemplate.getForObject("http://service-product/product/" + id, Product.class);
    }

    // 熔斷降級方法
    public Product orderBlockHandler(Long id) { Product product = new Product(); product.setId(-2l); product.setProductName("觸發熔斷降級方法"); return product; } // 拋出異常降級方法
    public Product orderFallback(Long id) { Product product = new Product(); product.setId(-1l); product.setProductName("觸發拋出異常降級方法"); return product; }
}

      在需要被保護的方法上使用 @SentinelResource 注解進行熔斷配置。與Hystrix不同的是,Sentinel對拋出異常和熔斷降級做了更加細致的區分,通過 blockHandler 指定熔斷降級方法,通過 fallback 指定觸發異常執行的降級方法。
      對於@SentinelResource的其他配置如下表:

      

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

      特別地,若 blockHandler 和 fallback 都進行了配置,則被限流降級而拋出 BlockException 時只會進入 blockHandler 處理邏輯。
      若未配置 blockHandler 、 fallback 和 defaultFallback ,則被限流降級時會將 BlockException 直接拋出。

  Feign實現熔斷:

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

      配置文件打開 sentinel 對 feign 的支持: feign.sentinel.enabled=true
      加入 openfeign starter 依賴使 sentinel starter 中的自動化配置類生效

    1.引入依賴

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

    2.開啟sentinel 支持

#配置feign
feign:
  sentinel:
    enabled: true

    3.配置FeignClient

      編寫FeignClient接口的實現類

      基於Feign實現熔斷降級,需要實現自定義的ProductFeginClient接口,且實現類需要掃描到容器中(@Component),降級方法就是實現接口的方法

@Component
public class ProductFeignClientImpl implements ProductFeignClient {

    /**
     * 熔斷降級的方法
     * @param id
     * @return
     */
    @Override
    public Product findById(Long id) {
        Product product = new Product();
        product.setId(-1L);
        product.setProductName("熔斷,觸發降級方法");
        return product;
    }
}

      修改FeignClient添加hystrix熔斷

/**
 * 聲明需要調用的服務名稱
 * @FeignClient
 *      name:服務提供者的服務名稱
 *      fallback:配置熔斷發生的降級方法實現類
 */
@FeignClient(name = "service-product", fallback = ProductFeignClientImpl.class)
public interface ProductFeignClient {

    /**
     * 配置需要調用的微服務接口
     */
    @GetMapping(value = "/product/{id}")
    public Product findById(@PathVariable("id") Long id);
}

    Feign 對應的接口中的資源名策略定義:httpmethod:protocol://requesturl。 @FeignClient 注解中的所有屬性,Sentinel 都做了兼容。

      ProductFeginClient 接口中方法 findById 對應的資源名為 GET:http://service-product/product/{id},根據注冊中心最終轉成需要調用的微服務的地址
    4.啟動測試

      .........

    

     

      注意:此工廠類必須放置在其實現接口的同級包或子包下

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM