这篇文章,主要介绍微服务组件之Sentinel服务熔断、服务降级、流量控制。
目录
一、Sentinel组件
1.1、Sentinel介绍
1.2、Sentinel环境搭建
(1)引入依赖
(2)资源和规则
1.3、使用SphU定义资源
(1)定义资源
(2)定义规则
1.4、使用SphO定义资源
(1)定义资源
(2)定义规则
1.5、使用@SentinelResource注解定义资源
(1)定义资源
(2)定义规则
1.6、熔断降级规则
(1)案例代码
(2)五种降级规则
一、Sentinel组件
1.1、Sentinel介绍
Sentinel是Spring Cloud Alibaba提供的一个专门用于服务容错、服务熔断、服务限流的微服务组件,它和hystrix组件的作用是类似的,但是Sentinel提供的功能比hystrix更加强大,Sentinel分为两部分,一部分是Sentinel核心库,另外一部分是Dashboard控制台,Dashboard控制台可以查看监控的信息,接口的调用情况等。
有两种使用Sentinel组件的方式,分别是:
- 第一种:引入Sentinel核心库依赖,然后通过Java代码的方式编写流控规则。
- 第二种:通过Dashboard控制台直接添加流控规则。
1.2、Sentinel环境搭建
Sentinel可以和很多的框架进行整合,并且也可以单独的使用,例如:和SpringCloud整合、和SpringBoot整合、Dubbo整合等,这里我就和SpringCloud进行整合。
(1)引入依赖
<!-- 引入 web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入 sentinel 依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
引入sentinel依赖之后,基本的环境就搭建好了,接下来就是使用Sentinel进行流量控制等代码的编写。
(2)资源和规则
在Sentinel中有两种概念需要了解下,分别是:资源和规则。
资源就是指项目中的一个请求资源,可以将一段代码、一个方法看作是资源,Sentinel就是以【资源】的形式进行流控设置,定义资源之后,还需要给这个资源设置相对应的流控规则,规则也就是说,这个资源什么情况下,需要发生熔断、降级、限流等等操作呢,这些操作就是规则。
- 一般情况下,我们都使用方法名、URL、微服务名称作为资源名称来描述某个资源。
- 流量控制、熔断降级、系统保护、来源访问控制、热点参数等等规则。
Sentinel提供了多种资源的定义方式,可以通过【@SentinelResource】注解定义资源,也可以通过Java代码的方式手动的定义资源。下面分别介绍一下,几种定义资源和规则的方式。
1.3、使用SphU定义资源
SphU是Sentinel提供的一个类,SphU是采用【try...catch】异常的方式来实现流控配置,当发生流控的时候,就会抛出一个BlockException异常。
(1)定义资源
@GetMapping("/sphU")
public String demo01() {
Entry entry = null;
try {
// 1、开启流控
entry = SphU.entry("sphU_demo01");
System.out.println("这里就是执行具体业务逻辑");
} catch (BlockException e) {
e.printStackTrace();
// 记录流控异常日志
Tracer.traceEntry(e, entry);
// 2、当发生流控的时候,就会进入这个异常块里面
return "Sentinel发生流控,请稍后重试!";
} finally {
if (entry != null) {
// 3、退出流控
entry.exit();
}
}
return "接口调用成功";
}
(2)定义规则
/**
* 注入流控规则
*/
@PostConstruct
private void initFlowRule() {
List<FlowRule> ruleList = new ArrayList<>();
// 创建资源对应的流控规则
FlowRule flowRule = new FlowRule();
// 设置当前这个规则属于哪个资源的
// 注意:不要用错方法,是调用【serResource()】方法,而不是【serRefResource()】,方法用错后,sentinel流控不生效
flowRule.setResource("sphU_demo01");
// 设置流控规则类型,这采用 QPS 方式
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置 QPS 的限制数量
flowRule.setCount(1);
ruleList.add(flowRule);
// 将流控规则添加到Sentinel里面
FlowRuleManager.loadRules(ruleList);
}
启动工程,然后浏览器访问【/api/sentinel/sphU】接口,连续多次刷新页面,此时就会出现流控情况,从而抛出异常。
1.4、使用SphO定义资源
SphO也是Sentinel提供的一个类,它是采用【if...else】的方式来实现流控,当触发流控的时候,对应方法会返一个boolean类型,false表示发生了流控,我们就可以根据方法的返回值,进行代码的处理。
(1)定义资源
@GetMapping("/sphO")
public String demo02() {
boolean entry = SphO.entry("sphO_demo02");
if (entry) {
try {
System.out.println("执行具体业务逻辑...");
// 没有发生流控,正常执行业务逻辑代码
return "接口调用成功";
} finally {
// 关闭流控
SphO.exit();
}
} else {
// 发生流控
return "Sentinel发生流控,请稍后重试!";
}
}
(2)定义规则
/**
* 注入流控规则
*/
@PostConstruct
public void initFlowRule() {
List<FlowRule> ruleList = new ArrayList<>();
// 创建资源对应的流控规则
FlowRule flowRule = new FlowRule();
flowRule.setResource("sphO_demo02");
// 设置当前这个规则属于哪个资源的
// 设置流控规则类型,这采用 QPS 方式
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置 QPS 的限制数量
flowRule.setCount(1);
ruleList.add(flowRule);
// 将流控规则添加到Sentinel里面
FlowRuleManager.loadRules(ruleList);
}
1.5、使用@SentinelResource注解定义资源
@SentinelResource注解,用于定义资源,这个注解中有下面这些属性:
- value:定义资源名称。
- blockHandler:定义流控降级之后调用的方法。
- 方法必须定义在同一个类中。
- 方法必须是public的。
- 方法返回值必须和原方法的返回值一致。
- 方法参数必须相同,但是最后一个参数可以添加一个异常类参数。
- blockHandlerClass:作用和blockHandler一致,只是单独写到一个类里面了。
- fallback:当对应方法抛出异常时候,会调用这个降级方法。
(1)定义资源
package com.gitcode.demo.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @version 1.0.0
* @Date: 2023/4/25 17:07
* @Copyright (C) ZhuYouBin
* @Description:
*/
@RestController
@RequestMapping("/api/sentinel/demo")
public class SentinelDemo {
@SentinelResource(value = "sentinel_demo", blockHandler = "blockHandlerMethod", fallback = "fallbackMethod")
@GetMapping("/resource")
public String demo02() {
System.out.println("执行具体业务逻辑...");
return "接口调用成功";
}
public String blockHandlerMethod() {
System.out.println("Sentinel发生流控,请稍后重试!");
return "Sentinel发生流控,请稍后重试!";
}
public String fallbackMethod(Throwable ex) {
System.out.println("Sentinel发生异常,请稍后重试!" + ex.getMessage());
return "Sentinel发生异常,请稍后重试!" + ex.getMessage();
}
}
(2)定义规则
/**
* 注入流控规则
*/
@PostConstruct
public void initFlowRule() {
List<FlowRule> ruleList = new ArrayList<>();
// 创建资源对应的流控规则
FlowRule flowRule3 = new FlowRule();
// 设置当前这个规则属于哪个资源的
flowRule3.setResource("sentinel_demo");
// 设置流控规则类型,这采用 QPS 方式
flowRule3.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置 QPS 的限制数量
flowRule3.setCount(1);
ruleList.add(flowRule);
// 将流控规则添加到Sentinel里面
FlowRuleManager.loadRules(ruleList);
}
1.6、熔断降级规则
通过Java代码的方式设置降级规则,降级规则采用【DegradeRule】类表示,通过这个类设置一些规则,然后将其保存到【DegradeRuleManager】类中的缓存里面即可。
(1)案例代码
/**
* 服务降级规则配置
*/
public void initDegradeRule() {
List<DegradeRule> degradeRuleList = new ArrayList<>();
// 设置降级规则
DegradeRule rule = new DegradeRule();
rule.setResource("资源名称");
// 指定触发降级的规则类型,有五种
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
// 设置发生异常时候数量
rule.setCount(2);
// 设置窗口时间
rule.setTimeWindow(10);
// 设置最小请求数量
rule.setMinRequestAmount(2);
degradeRuleList.add(rule);
// 加载到Sentinel里面
DegradeRuleManager.loadRules(degradeRuleList);
}
(2)五种降级规则
- DEGRADE_GRADE_EXCEPTION_COUNT:在指定时间内发生的异常次数降级。
- DEGRADE_GRADE_EXCEPTION_RATIO:在指定时间内发生的异常比率降级。
- DEGRADE_DEFAULT_MIN_REQUEST_AMOUNT:根据最小请求数量来实现降级。
- DEGRADE_GRADE_RT:根据响应比进行降级。
- DEGRADE_DEFAULT_SLOW_REQUEST_AMOUNT:最慢请求数量降级。
常用的就只有三个,分别是:异常数量、异常比率、响应比。
综上,这篇文章结束了,主要介绍微服务组件之Sentinel服务熔断、服务降级、流量控制。