這一節我們通過一個簡單的實例,學習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注解。