Alibaba Sentinel 是一個靈活的系統負載控制框架,經過控制接口和方法的調用來保證系統負載不會過大,維持正常響應速度。java
該項目的地址是 https://github.com/alibaba/Se... 。可是阿里的文檔一向看起來一頭霧水,因此本文介紹如何用一個最簡單的項目來上手。若是你熟悉 Spring Boot,那麼幾分鐘就能夠搞定。python
首先建立一個空的 Maven 項目,加上 Spring Boot 的依賴。pom.xml
看起來是下面的樣子,你能夠直接拿來用:git
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.demo</groupId> <artifactId>sentinel-test</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.3.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
這裏沒有將 Spring Boot 做爲 parent 項目,而是使用 <dependencyManagement>
,但效果是同樣的。github
在 pom.xml
中,首先添加 Spring Boot 依賴:spring
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
而後添加 Sentinel。在這個例子當中,咱們將用 註解 來實現負載控制,因此添加 sentinel-annotation-aspectj
依賴:apache
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-annotation-aspectj</artifactId> <version>1.5.1</version> </dependency>
添加了這兩個依賴就 OK 了。框架
Spring Boot 項目須要一個 main() 方法來啓動,咱們命名這個類爲 com.demo.SentinelTestApplication
,其內容以下:maven
@SpringBootApplication public class SentinelTestApplication { public static void main(String[] args) throws Exception { SpringApplication.run(SentinelTestApplication.class, args); } }
目前這個類尚未具體的內容,但咱們應該先運行一下,確保前面作的事情沒有出錯,而後再添加內容。spring-boot
咱們在 com.demo
包下建立一個名爲 DemoService 的類,這個類包含一個須要作訪問控制的 call()
方法:測試
@Service public class DemoService { private int counter; @SentinelResource(value = "DemoService.call", blockHandler = "callBlocked") public void call() { System.out.println("Hello (" + ++counter + ")"); } public void callBlocked(BlockException ex) { System.err.println("Blocked (" + ++counter + ") : " + ex.toString()); } }
所謂訪問控制就是當某個方法調用過於頻繁時,拒絕掉一部分調用。什麼才叫過於頻繁,咱們能夠經過自定義控制規則的方式來告訴 Sentinel。定義控制規則的部分放在後面介紹,咱們如今先關注業務自己,也就是 DemoService
類。
這個類包含兩個方法,其中 call()
方法是主角,正常的業務會調用這個方法;而 callBlocked()
則會在 call()
方法被拒絕掉時調用。
call()
方法上面的 @SentinelResource
註解標明瞭該方法是須要進行訪問控制的。Sentinel 將須要進行訪問控制的方法都稱做資源。這個註解有兩個屬性,value
屬性表示該資源的名稱,咱們經過名稱爲不一樣的資源制定不一樣的控制規則。blockHandler
屬性表示方法被拒絕時應該調用哪一個替代方法,這個替代方法必須在同一個類當中,且參數列表要在原方法參數列表的基礎上再添加一個 BlockException
類型的參數。
Sentinel 將控制規則包裝爲 com.alibaba.csp.sentinel.slots.block.flow.FlowRule
類。它包含下面幾個屬性:
resource
: 該規則針對哪一個資源;grade
: 從哪一個方面進行度量,如該方法的每秒調用次數,或同時調用該方法的線程數等等。count
: 度量閾值。超過這個閾值則會拒絕調用該方法。strategy
: 多個規則之間的搭配策略,具體參考這裏。下面咱們在 SentinelTestApplication
類裏面添加一個建立規則的方法,同時在 main()
方法裏面初始化它:
private static void initRules() throws Exception { FlowRule rule1 = new FlowRule(); rule1.setResource("DemoService.call"); rule1.setGrade(RuleConstant.FLOW_GRADE_QPS); rule1.setCount(5); // 每秒調用最大次數爲 5 次 List<FlowRule> rules = new ArrayList<>(); rules.add(rule1); // 將控制規則載入到 Sentinel com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager.loadRules(rules); } public static void main(String[] args) throws Exception { initRules(); // Sentinel 載入規則不必定非要在 Spring 初始化以前,在這以後也能夠。 SpringApplication.run(SentinelTestApplication.class, args); }
這樣 Sentinel 的規則就設置完畢。
Spring 提供 AOP 機制來實現方法調用的攔截,這是 Sentinel 實現控制規則的原理。Sentinel 提供 com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect
類,咱們要在 Spring 容器中加入這個 bean 才能讓 @SentinelResource
註解起做用。咱們須要在 SentinelTestApplication
類裏面添加下面的代碼:
@Bean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); }
固然,在實際項目裏面這一步能夠放到自動配置當中。
最後咱們寫一個方法來測試控制規則是否起做用,一樣是在 SentinelTestApplication
類裏面:
@Autowired private DemoService demoService; @PostConstruct public void run() { for (int i = 0; i < 10; i++) { demoService.call(); } }
實際運行 main()
方法時,你將會看到這樣的輸出:
Hello (1) Hello (2) Hello (3) Hello (4) Hello (5) Blocked (6) : com.alibaba.csp.sentinel.slots.block.flow.FlowException Blocked (7) : com.alibaba.csp.sentinel.slots.block.flow.FlowException Blocked (8) : com.alibaba.csp.sentinel.slots.block.flow.FlowException Blocked (9) : com.alibaba.csp.sentinel.slots.block.flow.FlowException Blocked (10) : com.alibaba.csp.sentinel.slots.block.flow.FlowException
經過這個例子,你應該大概瞭解 Sentinel 運做的機制了。在這個基礎上,Sentinel 還能實現控制規則的實時修改、遠程配置、狀態監控等等,它是個很是強大的框架。