Spring Cloud Alibaba(三)Sentinel之熔斷降級

Spring Cloud Alibaba(三)Sentinel之熔斷降級

本項目演示如何使用 Sentinel 完成 Spring Cloud 應用的熔斷降級調用。java

Sentinel 是阿里巴巴開源的分佈式系統的流量防衛組件,Sentinel 把流量做爲切入點,從流量控制,熔斷降級,系統負載保護等多個維度保護服務的穩定性。git

OpenFeign是一款聲明式、模板化的HTTP客戶端, Feign能夠幫助咱們更快捷、優雅地調用HTTP API,須要瞭解OpenFeign使用基礎,能夠參考cloud-feign示例源碼github

本項目服務註冊中心使用nacos,服務提供者使用Spring Cloud Alibaba(一) 如何使用nacos服務註冊和發現建立的ali-nacos-provider服務web

Sentinel介紹

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

Sentinel 具備如下特徵:json

  • 1.豐富的應用場景

Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量能夠承受的範圍)、消息削峯填谷、集羣流量控制、實時熔斷下游不可用應用等。app

  • 2.完備的實時監控

Sentinel 同時提供實時的監控功能。您能夠在控制檯中看到接入應用的單臺機器秒級數據,甚至 500 臺如下規模的集羣的彙總運行狀況。框架

  • 3.普遍的開源生態

Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只須要引入相應的依賴並進行簡單的配置便可快速地接入 Sentinel。分佈式

  • 4.完善的 SPI 擴展點

Sentinel 提供簡單易用、完善的 SPI 擴展接口。您能夠經過實現擴展接口來快速地定製邏輯。例如定製規則管理、適配動態數據源等。ide

Sentinel 分爲兩個部分

  • 核心庫(Java 客戶端)不依賴任何框架/庫,可以運行於全部 Java 運行時環境,同時對 Dubbo / Spring Cloud 等框架也有較好的支持。
  • 控制檯(Dashboard)基於 Spring Boot 開發,打包後能夠直接運行,不須要額外的 Tomcat 等應用容器。

Sentinel主要特性

Sentinel 主要特性

Sentinel開源生態

Sentinel 開源生態

熔斷降級

對調用鏈路中不穩定的資源進行熔斷降級是保障高可用的重要措施之一。因爲調用關係的複雜性,若是調用鏈路中的某個資源不穩定,最終會致使請求發生堆積。Sentinel 熔斷降級會在調用鏈路中某個資源出現不穩定狀態時(例如調用超時或異常比例升高),對這個資源的調用進行限制,讓請求快速失敗,避免影響到其它的資源而致使級聯錯誤。當資源被降級後,在接下來的降級時間窗口以內,對該資源的調用都自動熔斷(默認行爲是拋出 DegradeException)

降級策略

  • 平均響應時間 (DEGRADE_GRADE_RT):當 1s 內持續進入 5 個請求,對應時刻的平均響應時間(秒級)均超過閾值(count,以 ms 爲單位),那麼在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 爲單位)以內,對這個方法的調用都會自動地熔斷(拋出 DegradeException)。
  • 異常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):當資源的每秒請求量 >= 5,而且每秒異常總數佔經過量的比值超過閾值(DegradeRule 中的 count)以後,資源進入降級狀態。
  • 異常數 (DEGRADE_GRADE_EXCEPTION_COUNT):當資源近 1 分鐘的異常數目超過閾值以後會進行熔斷。

熔斷降級代碼實現

服務提供方

建立ali-nacos-provider項目

  1. 首先, 依賴nacos 註冊中心
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  1. 定義服務提供方接口
@RestController
@Slf4j
public class HelloController {
    @GetMapping(value = "/hello/{str}", produces = "application/json")
    public String hello(@PathVariable String str) {
        log.info("-----------收到消費者請求-----------");
        log.info("收到消費者傳遞的參數:" + str);
        String result = "我是服務提供者,見到你很高興==>" + str;
        log.info("提供者返回結果:" + result);
        return result;
    }
}

服務提消費方

建立ali-nacos-sentinel-feign項目

1.首先,pom.xml添加依賴

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

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

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

    </dependencies>

2.定義FeignClient,及其降級配置

  • 定義FeignClient
package com.easy.ansFeign.service;

import com.easy.ansFeign.fallback.HelloServiceFallbackFactory;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "ali-nacos-provider", fallbackFactory = HelloServiceFallbackFactory.class)
public interface HelloService {

    /**
     * 調用服務提供方的輸出接口.
     *
     * @param str 用戶輸入
     * @return hello result
     */
    @GetMapping("/hello/{str}")
    String hello(@PathVariable("str") String str);
}
  • 定義fallback 工廠,獲取異常
@Component
public class HelloServiceFallbackFactory implements FallbackFactory<HelloServiceFallback> {

    @Override
    public HelloServiceFallback create(Throwable throwable) {
        return new HelloServiceFallback(throwable);
    }
}
  • 定義具體的fallback 實現
public class HelloServiceFallback implements HelloService {

    private Throwable throwable;

    HelloServiceFallback(Throwable throwable) {
        this.throwable = throwable;
    }

    /**
     * 調用服務提供方的輸出接口.
     *
     * @param str 用戶輸入
     * @return
     */
    @Override
    public String hello(String str) {
        return "服務調用失敗,降級處理。異常信息:" + throwable.getMessage();
    }
}
  • 測試入口
@RestController
public class TestController {

    @Autowired
    private HelloService helloService;

    @GetMapping("/hello-feign/{str}")
    public String feign(@PathVariable String str) {
        return helloService.hello(str);
    }
}

使用示例

示例關聯項目

Spring Cloud Alibaba(一) 如何使用nacos服務註冊和發現基礎上,咱們新建了ali-nacos-sentinel-feign項目,並調用ali-nacos-provider項目用做該示例的服務提供方,有如下二個項目作測試。

ali-nacos-provider:服務提供者,服務名:ali-nacos-provider,端口:9000
ali-nacos-sentinel-feign:服務消費者,服務名:ali-nacos-sentinel-feign,端口:9102

運行示例測試

首先要啓動服務註冊中心 nacos、ali-nacos-provider服務及ali-nacos-sentinel-feign服務

  • 訪問地址: http://localhost:9102/hello-feign/yuntian

返回

我是服務提供者,見到你很高興==>yuntian

表示咱們的服務成功調用到了

  • 關閉ali-nacos-provider服務,訪問: http://localhost:9102/hello-feign/yuntian

返回

服務調用失敗,降級處理。異常信息:com.netflix.client.ClientException: Load balancer does not have available server for client: ali-nacos-provider

表示執行了咱們預約的回調,服務成功降級了。

資料

相關文章
相關標籤/搜索