本来目的只是限流,在程序里面可以定义规则。但是鉴于接口限流规则应该随着访问热度而改变,使用硬编码方式不可取,这样就需要借助于Sentinel控制台程序在网页端动态进行管理。所以我们需要先启动控制台程序。
去https://github.com/alibaba/Sentinel/tags下载一个合适的Sentinel控制台版本。
https://github.com/alibaba/Sentinel/releases/download/v1.8.0/sentinel-dashboard-1.8.0.jar
启动控制台,使用端口8756(霸气外露).
java -server -Xms64m -Xmx256m -Dserver.port=8756 -Dcsp.sentinel.dashboard.server=localhost:8756 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar
一、创建一个Springboot工程
二、添加Pom依赖
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<sentinel.version>1.8.0</sentinel.version>
</properties>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>${sentinel.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>${sentinel.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>${sentinel.version}</version>
</dependency>
我的控制要程序和Pom依赖选用的版本是一致的。
二、创建测试接口
package com.chris.sentinel;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
/**
* @author Chris Chan
* Create on 2021/5/31 13:12
* Use for:
* Explain:
*/
@RestController
@RequestMapping("api/test")
public class TestController {
@PostConstruct
public void init() {
//RuleManager.initFlowRules();
}
/**
* 抛异常限流
* @return
*/
@GetMapping("test")
public String test() {
try (Entry test = SphU.entry("test");) {
return "Called api/test/test success.";
} catch (BlockException e) {
e.printStackTrace();
return "System is busily.Please wait.";
}
}
/**
* aspect注解限流
* @return
*/
@SentinelResource(value = "test2", blockHandlerClass = TestBlockHandlerManager.class, blockHandler = "test2BlockHandler")
@GetMapping("test2")
public String test2() {
return "Called api/test/test2 success.";
}
}
创建了两个接口,test是用于测试异常限流的,test2是用于测试在控制台中动态创建限流规则的。init方法中注释掉的部分适用于开启本地创建限流规则,即硬编码模式。
三、创建本地限流规则
package com.chris.sentinel;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import java.util.ArrayList;
import java.util.List;
/**
* @author Chris Chan
* Create on 2021/5/31 13:14
* Use for:
* Explain: 限流规则管理
*/
public class RuleManager {
/**
* 初始化限流规则
*
* @return
*/
public static void initFlowRules() {
List<FlowRule> ruleList = new ArrayList<>(16);
FlowRule flowRule = new FlowRule();
flowRule.setResource("test");
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setCount(2);
ruleList.add(flowRule);
FlowRuleManager.loadRules(ruleList);
}
}
如果使用了这个规则,不用连接控制台,只要快速访问test接口,在一秒内超过两次,就会被限流,返回系统繁忙。
四、创建SentinelResourceAspect的bean
package com.chris.sentinel;
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Chris Chan
* Create on 2021/5/31 14:22
* Use for:
* Explain:
*/
@Configuration
public class SentinelConfig {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
这个将用于test2的注解.。
五、创建限流处理器
package com.chris.sentinel;
import com.alibaba.csp.sentinel.slots.block.BlockException;
/**
* @author Chris Chan
* Create on 2021/5/31 14:25
* Use for:
* Explain:
*/
public class TestBlockHandlerManager {
/**
* 必须为静态方法
* @param e
* @return
*/
public static String test2BlockHandler(BlockException e) {
return "System is busily.Please wait.";
}
}
这个也是适用于test2,需要在注解上指明被限流后如何降级处理。如果处理方法和接口在同一个类,则不需要指明类,否则需要指明处理方法所在的类,而且方法必须是静态方法,否则不可识别。
六、添加运行参数。以上的创建涉及到三个方面的测试。由于我们还需要连接到控制台,所以需要增加必要的运行参数。在Edit Configurations...中为VM options添加参数
-Dproject.name=testApp -Dcsp.sentinel.dashboard.server=localhost:8756
七、把程序运行起来。此时控制台空空如也。我们调用一下接口,刷新控制台,就会发现客户端。
在控制台添加流控规则,只要资源名称跟接口需要使用的资源名称相同,就会将规则应用到对应接口上。
快速刷新接口调用,可以获取到被限流之后返回的系统繁忙信息,还能在控制台实时监控看到数据统计,访问量有多少,被限制了多少等等。