1. 程式人生 > >Spring Cloud Alibaba 之 Sentinel 限流規則和控制檯例項

Spring Cloud Alibaba 之 Sentinel 限流規則和控制檯例項

這一節我們通過一個簡單的例項,學習Sentinel的基本應用。

一、Sentinel 限流核心概念

在學習Sentinel的具體應用之前,我們先來了解一下Sentinel中兩個核心的概念,資源和規則。

資源

資源 是 Sentinel 中的核心概念之一。既然是限流,或者系統保護,那麼是針對什麼做限流?保護的是什麼?就是我們所說的資源。
其實 Sentinel 對資源的定義,和併發程式設計中 Synchronized的使用很類似,這裡的資源,可以是服務裡的方法,也可以是一段程式碼。

規則

定義了資源之後,就是如何對資源進行保護,對資源進行保護的手段,就是我們說的規則。

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

  • 定義資源
  • 定義規則
  • 檢驗規則是否生效

Sentinel 的所有規則都可以在記憶體態中動態地查詢及修改,修改之後立即生效。

二、Spring Boot 限流例項

下面我實現一個使用 Sentinel 的 Hello World 例項。

1、引入 Sentinel 依賴

首先要在工程中加入 Sentinel依賴,
使用Maven管理依賴的專案,只要在 pom.xml 檔案中加入以下程式碼即可:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.7.1</version>
</dependency>

非Maven專案,可以下載Jar包檔案到本地,中央倉庫地址Maven Center Repository。

這裡使用註解的方式,還需要加入 Sentinel 的切面支援依賴,Pom檔案如下

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
    <version>1.7.1</version>
</dependency>

2、配置資源和規則

首先編寫啟動類和程式碼入口,

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(ServiceApplication.class, args);
    }
}
@RestController
public class TestController {

    @Autowired
    private TestService service;

    @GetMapping(value = "/hello/{name}")
    public String apiHello(@PathVariable String name) {
        return service.sayHello(name);
    }
}

在服務層定義資源,這裡使用註解 @SentinelResource,@SentinelResource 註解用來標識資源是否被限流、降級。

@Service
public class TestService {

    @PostConstruct
    private void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("HelloWorld");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 設定QPS為1
        rule.setCount(1);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }

    @SentinelResource(value = "HelloWorld",blockHandler="degradeMethod")
    public String sayHello(String name) {
        return "Hello, " + name;
    }

    /**
     * 降級方法,限流後應用
     * @return
     */
    public String degradeMethod(String name, BlockException blockException){

        return "請求被限流,觸發限流規則="+blockException.getRule().getResource();
    }

}

定義了被隔離的資源以後,就是規定具體的限流和降級的規則,這裡在initFlowRules()方法中初始化規則,添加了一個服務限流後觸發的degradeMethod()方法。

3、限流演示

我在限流規則裡定義了最大QPS不能超過1,反覆重新整理幾次頁面請求,就會被限流。

4、連線控制檯

連線控制檯需要新增下面的依賴:

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

啟動時加入 JVM 引數 -Dcsp.sentinel.dashboard.server=consoleIp:port。
-Dcsp.sentinel.dashboard.server=192.168.43.120:8719
這裡我把啟動引數新增在Idea Configuration下的VM options中,
啟動應用後重新整理控制檯,可以看到應用已經註冊上去。

三、主流框架的快速適配

上面演示的是一個極簡單的限流例子,資源需要開發者自己去定義,那麼在一些約定的場景,比如在微服務呼叫下,Sentinel能否自動識別服務呼叫,不改動程式碼就可以進行限流降級呢?

答案是肯定的,針對主流的框架,Sentinel 提供了許多開箱即用的特性支援,包括阿里自家的 Dubbo,Spring Cloud,以及Spring WebFlux,gRPC等框架。

適配 Dubbo

Sentinel 提供 Dubbo 的相關適配 Sentinel Dubbo Adapter,主要包括針對 Service Provider 和 Service Consumer 實現的 Filter。

sentinel-apache-dubbo-adapter(相容 Apache Dubbo 2.7.x 及以上版本,自 Sentinel 1.5.1 開始支援)
sentinel-dubbo-adapter(相容 Dubbo 2.6.x 版本)
對於 Apache Dubbo 2.7.x 及以上版本,使用時需引入以下模組(以 Maven 為例):

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-apache-dubbo-adapter</artifactId>
    <version>${version}</version>
</dependency>

對於 Dubbo 2.6.x 及以下版本,使用時需引入以下模組(以 Maven 為例):

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-dubbo-adapter</artifactId>
    <version>${version}</version>
</dependency>

引入此依賴後,Dubbo 的服務介面和方法(包括呼叫端和服務端)就會成為 Sentinel 中的資源,在配置了規則後就可以自動享受到 Sentinel 的防護能力。

適配 Spring Cloud

Sentinel 對 Spring Cloud 的支援,也就是 Spring Cloud Alibaba全家桶,預設為 Sentinel 整合了 Servlet、RestTemplate、FeignClient 和 Spring WebFlux。Sentinel 在 Spring Cloud 生態中,不僅補全了 Hystrix 在 Servlet 和 RestTemplate 這一塊的空白,而且還完全相容了 Hystrix 在 FeignClient 中限流降級的用法,並且支援執行時靈活地配置和調整限流降級規則。

在Spring Cloud 專案中引入 Sentinel,新增如下依賴就可以,

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

總結

這節給大家演示了一個 Sentinel的應用例項,並且介紹了Sentinel 和主流框架的整合,下一節的內容會深入解析 @SentinelResource註解