赞
踩
用到的依赖及配置
<!-- Sentinel核心服务 --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-core</artifactId> <version>1.8.6</version> </dependency> <!-- Sentinel核心服务 --> <!-- Sentinel本地应用接入控制台 --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-transport-simple-http</artifactId> <version>1.8.6</version> </dependency> <!-- Sentinel本地应用接入控制台 --> <!-- Sentinel提供注解无侵入定义资源 --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-annotation-aspectj</artifactId> <version>1.8.6</version> </dependency> <!-- Sentinel提供注解无侵入定义资源 -->
spring:
application:
name: sentinel
<!-- 版本与控制台保持一致即可 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.6</version>
</dependency>
<!-- 版本与控制台保持一致即可 -->
@RestController @RequestMapping("/user") public class UserController { @GetMapping("/add") public String create(){ try { // 设置一个资源名称为 Hello Entry ignored = SphU.entry("AddUser"); System.out.println("新建一个用户"); return "新建一个用户"; } catch (BlockException e) { System.out.println("系统繁忙,请稍后"); e.printStackTrace(); return "系统繁忙,请稍后"; } } /** * 使用代码编写流控规则,项目中不推荐使用,这是硬编码方式 * * 注解 @PostConstruct 的含义是:本类构造方法执行结束后执行 */ @PostConstruct public void initFlowRule() { /* 1.创建存放限流规则的集合 */ List<FlowRule> rules = new ArrayList<>(); /* 2.创建限流规则 */ FlowRule rule = new FlowRule(); /* 定义资源,表示 Sentinel 会对哪个资源生效 */ rule.setResource("AddUser"); /* 定义限流的类型(此处使用 QPS 作为限流类型) */ rule.setGrade(RuleConstant.FLOW_GRADE_QPS); /* 定义 QPS 每秒通过的请求数 */ rule.setCount(2); /* 3.将限流规则存放到集合中 */ rules.add(rule); /* 4.加载限流规则 */ FlowRuleManager.loadRules(rules); } @GetMapping("/edit") public String edit(){ return "编辑一个用户"; } }
下载 Sentinel 控制台 jar 包:https://github.com/alibaba/Sentinel/releases
启动 Sentinel 控制台,如下图所示
java -Dserver.port=9000 -jar sentinel-dashboard-1.8.6.jar
访问 Sentinel 控制台:http://127.0.0.1:9000/
账号/密码:sentinel/sentinel
<!-- Sentinel本地应用接入控制台,版本与控制台保持一致即可 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.6</version>
</dependency>
<!-- Sentinel本地应用接入控制台,版本与控制台保持一致即可 -->
-Dcsp.sentinel.dashboard.server=127.0.0.1:9000 Sentinel控制台的地址和端口号
-Dproject.name=sentinel 本地应用在控制台中的名称
第一次查看控制台,需要先访问一次被限流控制的接口,否则控制台中没有东西
快速在页面刷新,就会出现限流后的返回提示语
删除使用代码编写的流控规则,项目中不推荐使用
,这是硬编码方式
@RestController @RequestMapping("/user") public class UserController { @GetMapping("/add") public String create(){ try { // 设置一个资源名称为 Hello Entry ignored = SphU.entry("AddUser"); System.out.println("新建一个用户"); return "新建一个用户"; } catch (BlockException e) { System.out.println("系统繁忙,请稍后"); e.printStackTrace(); return "系统繁忙,请稍后"; } } @GetMapping("/edit") public String edit(){ return "编辑一个用户"; } }
Sentinel
支持通过 @SentinelResource
注解来定义资源,并配置 blockHandler
函数来进行限流之后的处理
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.0</version>
</dependency>
@Configuration
public class SentinelAspectConfiguration {
@Bean
public SentinelResourceAspect sentinelResourceAspect(){
return new SentinelResourceAspect();
}
}
@RestController @RequestMapping("/user") public class UserController { // value:资源名称 blockHandler:设置限流或降级处理的类 @SentinelResource(value = "AddUser", blockHandler = "exceptionHandler") @GetMapping("/add") public String create(){ return "新增一个用户"; } // 限流处理类 public String exceptionHandler(@NotNull BlockException e) { e.printStackTrace(); return "系统繁忙,请稍后再试"; } }
实现方式有以下几种
使用这种方式当资源发生限流后会抛出 BlockException
异常。这个时候可以捕获异常,进行限流之后的逻辑处理,关键代码如下
@RequestMapping(path = {"/hello"}, method = RequestMethod.GET)
@ResponseBody
public String hello() {
try {
Entry ignored = SphU.entry("Hello");
System.out.println("Hello Sentinel");
return "Hello Sentinel";
} catch (BlockException e) {
System.out.println("系统繁忙,请稍后");
e.printStackTrace();
return "系统繁忙,请稍后";
}
}
使用的 API
为 SphO
,限流后返回的值为 boolean
类型。注意:SphO.entry
必须和 SphO.exit
成对出现 否则会报错
@GetMapping("/boolean") public boolean returnBoolean() { // 使用限流规则 if (SphO.entry("Sentinel-boolean")){ try { System.out.println("Hello Sentinel"); return true; }finally { // 限流的出口 SphO.exit(); } } else { // 限流后进行的操作 System.out.println("系统繁忙,请稍后再试"); return false; } }
在启动类中添加 @EnableAsync
,表示 SpringBoot
项目开启异步调用支持
@SpringBootApplication
@EnableAsync
public class SentinelQuickStartApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelQuickStartApplication.class, args);
}
}
@Service
public class AsyncService {
// Async表示方法为异步调用
@Async
public void hello(){
System.out.println("异步调用开始======");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("异步调用结束=====");
}
}
@Autowired private AsyncService asyncService; @GetMapping("/async") public void async() { // 1.进行限流控制 AsyncEntry asyncEntry = null; try { asyncEntry = SphU.asyncEntry("Sentinel_Async"); // 限流入口 asyncService.hello(); // 异步调用方法 System.out.println("异步测试"); } catch (BlockException e) { e.printStackTrace(); System.out.println("系统繁忙请稍后再试"); } finally { if (asyncEntry != null) { asyncEntry.exit(); // 限流出口 } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。