如果不具备nacos的知识,推荐先看:spring cloud Alibaba——01 Nacos
一、安装Sentinel
- 下载地址:https://github.com/alibaba/Sentinel/releases
- 终端运行Sentinel
# 在jar包所在目录,cmd进入终端
java -jar sentinel-dashboard-1.8.2.jar
指定端口后台永久启动
[root@iz2zedg4ylq9iqtwm11wecz sentinel]# nohup java -Dserver.port=8849 -Dcsp.sentinel.dashboard.server=localhost:8849 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.3.jar 2>&1 &
[1] 9427
[root@iz2zedg4ylq9iqtwm11wecz sentinel]# nohup: ignoring input and appending output to ‘nohup.out’
- 访问:http://localhost:8080/
默认登录账号、密码:sentinel、sentinel - 成功页面
注意:Sentinel使用的是懒加载。当被监控的请求,第一次访问后才会被Sentinel记录下来。
二、Sentinel入门案例
官方文档:https://sentinelguard.io/zh-cn/docs/flow-control.html
Sentinel的使用可以分为三步:
- 定义资源
- 定义规则
- 检验规则是否生效
我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。使用 Sentinel 来进行资源保护,主要分为几个步骤:
先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。
1、导入pom
注意:本文的所有pom依赖的版本控制,都是基于父项目的。通过父项目,统一管理版本,避免依赖冲突。
父项目pom依赖:
<dependencyManagement>
<dependencies>
<!--spring boot 2.2.2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud alibaba 2.1.0.RELEASE-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
子项目依赖:
<dependencies>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel-datasource-nacos 因为Sentinel的断路规则配置是一次性的,
Sentinel server重启后配置就会丢失,所有需要持久化用到nacos 的配置中心-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel,这个配置可能会导入失败,可以更改版本号试试。注意使用2.1.x -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
</dependencies>
2、改yml
server.port=8001
spring.application.name=-sentinel-service-provider
# 指定注册中心
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# 指定sentinel监控中心
spring.cloud.sentinel.transport.dashboard=localhost:8080
3、主启动类
/**
* @author 15594
*/
@SpringBootApplication
@EnableDiscoveryClient
public class SentinelMain8001 {
public static void main(String[] args) {
SpringApplication.run(SentinelMain8001.class,args);
}
}
4、测试类
/**
* Sentinel实现断路(限流、熔断、降级等)
* @author 15594
*/
@RestController
public class SentinelController {
@GetMapping("/testA")
public String testA()
{
return "------testA";
}
@GetMapping("/testB")
public String testB()
{
return "------testB";
}
}
5、设置断路规则(核心)
这个一步只需要到Sentinel server 用户界面设置即可
比如:设置一个限流规则:
限流规则添加成功
再次访问:http://localhost:8001//testA
连续刷新
当每秒请求超过1次时就会触发服务降级。
三、配置断路规则
上面的入门案例我们也就配置过流量控制了。我们如何配置其他的断路规则呢?
sentinel为我们提供了以下的断路配置规则:
1、断路规则配置分类
其实sentinel断路规则按照配置方式
可以配置两种。
- 一种是
入门案例中的配置方式
,在sentinel提供的用户界面就行配置。(推荐使用
)
这种方式会随着服务(这个服务是受监控的服务)的关闭而丢失配置信息。因此需要将这些规则配置持久化
后面会讲如何实现持久化。 - 一种是通过代码配置。(
不推荐
)
这种方式是可以实现持久化的,但是会增加代码的耦合度,并且实现比较麻烦。
比如:
/**
* 定义资源
* */
@GetMapping("/testB")
public String testB() {
// 配置规则.
initFlowRules();
while (true) {
// 1.5.0 版本开始可以直接利用 try-with-resources 特性
Entry entry =null;
try {
entry = SphU.entry("HelloWorld");
// 被保护的逻辑
System.out.println("hello world");
return "------testB";
} catch (BlockException ex) {
// 处理被流控的逻辑
System.out.println("流量控制生效");
return "流量控制生效";
} finally {
if (entry != null) {
entry.exit();
}
}
}
}
/**
* 定义规则
* */
private static void initFlowRules(){
List<FlowRule> rules = new ArrayList<FlowRule>();
FlowRule rule = new FlowRule();
rule.setResource("HelloWorld");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// Set limit QPS to 20.
rule.setCount(1);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
2、规则的种类
Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效。同时 Sentinel 也提供相关 API,供您来定制自己的规则策略。
Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则 和 热点参数规则。
上面已经说过,规则的配置方式有两种,我们使用Sentinel 图形化界面进行配置 。
注意:官网上已经有这些规则的概念的详细介绍,我们结合Sentinel 用户界面上面的配置针对这些概念进行讲解。
2.1、流量控制规则 (FlowRule)
下面我们为testA添加一个流控规则:
资源名:唯一名称,有两种形式的值。方式一:请求路径的格式(资源名字前面有斜杠/),比如:/testA 这样就能将这个规则绑定给 /testA 这个请求。方式二:自己起一个名字资源,但是要唯一,然后通过注解@SentinelResource(value = “testB”)绑定给一个请求路径。
方式一:
如果资源名/testB,那么这个流控规则就会寻找一个请求路径为 /testB ,将规则绑定给/testB@GetMapping("/testB") //根据请求路径,绑定流控规则 public String testB() { return "------testB"; }
方式二:
如果资源名123,那么这个流控规则就会寻找一个通过注解标注为@SentinelResource(value = “123”)的请求,将规则绑定给这个请求。@SentinelResource(value = "123") @GetMapping("/testC") public String testC() { // initFlowRulesTestC(); return "------testC"; }
针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源),
可以当作将规则分类
。阈值类型/单机阈值:zhiyuan
- QPS(每秒钟的请求数量)︰当调用该API的QPS达到阈值的时候,进行限流。(
选择QPS后,单机阈值的值就表示,每秒请求的最大次数
) - 线程数:当调用该API的线程数达到阈值的时候,进行限流。(
选择线程数后,单机阈值的值就表示,同一时间同时访问的线程数为多少个,也就是支持多少个用户同时访问这个请求
)
- QPS(每秒钟的请求数量)︰当调用该API的QPS达到阈值的时候,进行限流。(
是否集群:不需要集群。
- 单机均摊 : 以单机为单位,单机请求数达到阈值后,集群限流
- 总体阈值 :以集群为单位,集群请求数达到阈值后,集群限流
流控模式:
- 直接:请求达到限流条件时,直接限流。
- 关联:当关联的资源B达到阈值时,就限流自己A。
举例 :用户 请求 A 调用(消费)B 。当B限流时(服务不可用),那么A也会限流自己。
- 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【API级别的针对来源】。
举例 :A->B->C
当 入口资源A限流时限流自己
流控效果:
- 快速失败:直接失败,抛异常。
- Warm up:根据Code Factor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值。
- 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效。
2.2、熔断降级规则 (DegradeRule)
2.3、系统保护规则 (SystemRule)
2.4、Sentinel热点key(常用
)
注意:热点规则(比较常用),可以理解为给请求的进一步定制断路规则
。
举例:
@SentinelResource(value = "testA",blockHandler = "deal_testA")
@GetMapping("/testA/{vip}/{name}")
public String testA(@PathVariable("vip") String vip,@PathVariable("name") String name) {
return "------testA";
}
public String deal_testA(String vip, String name,BlockException exception) {
return "触发限流";
}
访问携带参数vip的请求(出去vip=1的例外项),每秒只能请求成功一次。如:http://localhost:8001//testA/0/lihua
访问携带参数vip=1的请求,每秒能请求成功10次。如:http://localhost:8001//testA/1/lihua
四、注解@SentinelResource
注意:@SentinelResource需要配合@RestController(@Controller和@ResponseBody)使用,也就是。我们控制器只能返回数据,不能返回视图。不然,降级处理方法将会不起作用。
注意:这个注解标注的方法最好是pubic类型
@SentinelResource这个注解有以下属性:
1、value
value属性用来指定资源名
@SentinelResource(value = "testA")
2、entryType:
entry 类型,可选项(默认为 EntryType.OUT)
3、blockHandler / blockHandlerClass: (违反断路规则触发)
blockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException
。blockHandler 函数默认需要和原方法在同一个类中
。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象
,注意对应的函数必需为 static 函数
,否则无法解析。
/**
* Sentinel实现断路(限流、熔断、降级等)
* @author 15594
*/
@RestController
public class SentinelController {
@SentinelResource(value = "testA",blockHandler = "deal_testA",
blockHandlerClass = {BlockHandlerService.class})
@GetMapping("/testA/{vip}/{name}")
public String testA(@PathVariable("vip") String vip,@PathVariable("name") String name) {
return "------testA";
}
}
/**
* 违背断路规则后,触发的降级方法。为了降低代码耦合将这些方法统一放到一起
* @author 15594
*/
public class BlockHandlerService {
/**
* 注意对应的函数必需为 static 函数,否则无法解析。
* */
public static String deal_testA(String vip, String name, BlockException exception) {
return "触发限流";
}
}
注意:对应的BlockHandler函数必需为 static 函数,否则无法解析。
4、fallback:(请求异常触发)
fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:返回值类型必须与原函数返回值类型一致;方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
/**
* 注意:如果只配置fallback,可以不设置断路规则
* */
@SentinelResource(value = "testC",fallbackClass = { FallbackClassService.class },fallback = "deal_testC"
//默认降级方法,当有fallback指定的方法时不起效。
,defaultFallback = "defaultFallback" )
@GetMapping("/testC")
public String testC() {
//制造一个异常
int i = 1/0;
return "------testC";
}
/**
* 代码出现异常后,的降级处理方法,为了减少代码耦合度将这些方法放到一个类中管理
* @author 15594
*/
public class FallbackClassService {
/**
* 注意对应的函数必需为 static 函数,否则无法解析。
* */
public static String deal_testC(Throwable e) {
System.out.println(e.getMessage());
return "程序异常,降级处理";
}
/**
* 返回值类型必须与原函数返回值类型一致;
* 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
* 为了解决代码膨胀,我们给一个默认的降级方法
* */
public static String defaultFallback(Throwable e){
System.out.println(e.getMessage());
return "默认降级方法";
}
}
**注意:**降级方法,额外携带的参数只能是 Throwable 类型(只能写Throwable e,不能写它的子类 ,不然会报错
)的参数用于接收对应的异常。降级函数必需为 static 函数,否则无法解析。
5、defaultFallback(since 1.6.0):
默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所以类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型
)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效
。defaultFallback 函数签名要求:返回值类型必须与原函数返回值类型一致;方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
注意:通过指定默认降级方法可以有效防止代码膨胀
6、exceptionsToIgnore(since 1.6.0):
用于指定哪些异常被排除掉,不会计入异常统计中
,也不会进入 fallback 逻辑中,而是会原样抛出。
五、持久化Sentinel断路规则
在前面我们已经知道,通过Sentinel用户界面配置的断路规则会,随着服务的重启而丢失。如何将这些配置持久化呢?
Sentinel 目前支持以下数据源扩展(持久化):
Pull-based: 动态文件数据源、Consul, Eureka`注意:下面这种方式是通过Nacos Push方式实现,并且这种方式可以远程动态刷新规则配置。` ### 1、导入pom 在之前的基础上增加一个sentinel-datasource-nacos依赖 ```xml com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator com.alibaba.csp sentinel-datasource-nacos com.alibaba.cloud spring-cloud-starter-alibaba-sentinel 2.1.1.RELEASE ``` ### 2、改yml
Push-based: ZooKeeper, Redis, Nacos, Apollo, etcd
server.port=8001
spring.application.name=-sentinel-service-provider
# 指定注册中心
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# 指定sentinel监控中心
spring.cloud.sentinel.transport.dashboard=localhost:8080
# 持久化sentinel规则配置到nacos ------ 新增
# 配置中心地址
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=localhost:8848
# 命名空间
spring.cloud.sentinel.datasource.ds1.nacos.namespace=4a46ce6a-c692-4d85-8291-8961bd1ee52b
# data id
spring.cloud.sentinel.datasource.ds1.nacos.data-id=sentinel-datasource-service
# 组id
spring.cloud.sentinel.datasource.ds1.nacos.group-id=DEFAULT_GROUP
# 配置数据类型
spring.cloud.sentinel.datasource.ds1.nacos.data-type=json
spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow
3、到nacos配置一个断路规则
[
{
"resource": "testA",
"IimitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
//可以继续添加
]
4、通过注解绑定请求
@SentinelResource(value = "testA")
@GetMapping("/testA/{vip}/{name}")
public String testA(@PathVariable("vip") String vip,@PathVariable("name") String name) {
return "------testA";
}
5、如何编写配置
比如:我们编写一个热点规则。
通过官网我们可以获取到对应的属性名:官网
注意:使用时把注释去掉。
流控规则
根据实际的需要改变减少对应的参数即可[ { // 资源名 "resource": "/test", // 针对来源,若为 default 则不区分调用来源 "limitApp": "default", // 限流阈值类型(1:QPS;0:并发线程数) "grade": 1, // 阈值 "count": 1, // 是否是集群模式 "clusterMode": false, // 流控效果(0:快速失败;1:Warm Up(预热模式);2:排队等待) "controlBehavior": 0, // 流控模式(0:直接;1:关联;2:链路) "strategy": 0, // 预热时间(秒,预热模式需要此参数) "warmUpPeriodSec": 10, // 超时时间(排队等待模式需要此参数) "maxQueueingTimeMs": 500, // 关联资源、入口资源(关联、链路模式) "refResource": "rrr" } ]
降级(熔断)规则
根据实际的需要改变减少对应的参数即可[ { // 资源名 "resource": "/test1", "limitApp": "default", // 熔断策略(0:慢调用比例,1:异常比率,2:异常计数) "grade": 0, // 最大RT、比例阈值、异常数 "count": 200, // 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入) "slowRatioThreshold": 0.2, // 最小请求数 "minRequestAmount": 5, // 当单位统计时长(类中默认1000) "statIntervalMs": 1000, // 熔断时长 "timeWindow": 10 } ]
热点规则
根据实际的需要改变减少对应的参数即可[ { // 资源名 "resource": "/test1", // 限流模式(QPS 模式,不可更改) "grade": 1, // 参数索引 "paramIdx": 0, // 单机阈值 "count": 13, // 统计窗口时长 "durationInSec": 6, // 是否集群 默认false "clusterMode": 默认false, // "burstCount": 0, // 集群模式配置 "clusterConfig": { // "fallbackToLocalWhenFail": true, // "flowId": 2, // "sampleCount": 10, // "thresholdType": 0, // "windowIntervalMs": 1000 }, // 流控效果(支持快速失败和匀速排队模式) "controlBehavior": 0, // "limitApp": "default", // "maxQueueingTimeMs": 0, // 高级选项 "paramFlowItemList": [ { // 参数类型 "classType": "int", // 限流阈值 "count": 222, // 参数值 "object": "2" } ] } ]
系统规则
负值表示没有阈值检查。不需要删除参数
[ { // RT "avgRt": 1, // CPU 使用率 "highestCpuUsage": -1, // LOAD "highestSystemLoad": -1, // 线程数 "maxThread": -1, // 入口 QPS "qps": -1 } ]
受权规则
根据实际的需要改变对应的参数即可[ { // 资源名 "resource": "sentinel_spring_web_context", // 流控应用 "limitApp": "/test", // 授权类型(0代表白名单;1代表黑名单。) "strategy": 0 } ]
参考: Spring Cloud Alibaba Sentinel(八)持久化数据及配置json
六、Sentinel整合负载均衡
项目结构
1、导入pom
<dependencies>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel-datasource-nacos 因为Sentinel的断路规则配置是一次性的,
Sentinel server重启后配置就会丢失,所有需要持久化用到nacos 的配置中心-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<!--SpringCloud openfeign整合了ribbon,使用的负载均衡本质上还是ribbon的。
同时openfeign还提供了服务降级功能,和帮我们动态生成通信实现类,使得我们控制层可以通过调用接口,实现服务间的通信,减少代码耦合 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
2、改yml
server.port=81
spring.application.name=-sentinel-openfeign-service-consumer
# 指定注册中心
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# 指定sentinel监控中心
spring.cloud.sentinel.transport.dashboard=localhost:8080
# 持久化sentinel规则配置到nacos ------ 这个需要在nacos配置中心创建远程配置文件,用于持久化断路规则和远程动态修改断路规则
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.ds1.nacos.namespace=4a46ce6a-c692-4d85-8291-8961bd1ee52b
spring.cloud.sentinel.datasource.ds1.nacos.data-id=sentinel-openfeign-service-consumer
spring.cloud.sentinel.datasource.ds1.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds1.nacos.data-type=json
spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow
# 如果为 true,则 OpenFeign 客户端将被 Sentinel 断路器包裹(用于服务降级,如果不使用,@FeignClient(fallback = "")带的降级属性可以不开启)
#feign.sentinel.enabled=true
# 指定负载均衡策略:注意:如果这句代码没有提示,不要觉得写错了(我们也可以根据全限定类名,指定我们自己编写的负载均衡策略)
# 注意:前面的service-provider为:服务地址,也就是@FeignClient(value = "service-provider") 中的value的值
service-provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
#请求连接超时时间
service-provider.ribbon.ConnectTimeout=500
#请求处理的超时时间
service-provider.ribbon.ReadTimeout=1000
#对所有请求都进行重试
service-provider.ribbon.OkToRetryOnAllOperations=true
#切换实例的重试次数
service-provider.ribbon.MaxAutoRetriesNextServer=2
#对当前实例的重试次数
service-provider.ribbon.MaxAutoRetries=1
#此外ribbon还提供了以下负载均衡策略
#com.netflix.loadbalancer.RandomRule #配置规则 随机
#com.netflix.loadbalancer.RoundRobinRule #配置规则 轮询
#com.netflix.loadbalancer.RetryRule #配置规则 重试
#com.netflix.loadbalancer.WeightedResponseTimeRule #配置规则 响应时间权重
#com.netflix.loadbalancer.BestAvailableRule #配置规则 最空闲连接策略
到nacos配置中心创建远程配置文件:
[{
"resource": "consumer",
"IimitApp": "default",
"grade": 1,
"count": 2,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}]
3、主启动类
/**
* 主启动类
* // @EnableDiscoveryClient nacos 开启注册中心
* // @EnableFeignClients 开启openfeign
* @author 15594
*/
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class MainSentinelFeign81 {
public static void main(String[] args) {
SpringApplication.run(MainSentinelFeign81.class,args);
}
}
4、业务层
openFeign 接口:
/**
*
* 需要调用的生产者API
* openFeign会帮我们创建具体实现类。
* @author 15594
*/
@FeignClient(value = "service-provider")
public interface ProviderService {
@RequestMapping("/provider")
public String provider();
}
sentinel 降级处理:
/**
* 违背断路规则后,触发的降级方法。为了降低代码耦合将这些方法统一放到一起
* @author 15594
*/
public class BlockHandlerService {
public static String provider(BlockException exception) {
System.out.println(exception.getRuleLimitApp());
return "违反断路规则,降级处理";
}
}
/**
* 代码出现异常后,的降级处理方法,为了减少代码耦合度将这些方法放到一个类中管理
* @author 15594
*/
public class FallbackClassService {
public static String provider(Throwable throwable) {
System.out.println(throwable.getMessage());
return "程序异常,降级处理";
}
}
5、控制层
/**
* @author 15594
*/
@RestController
public class ConsumerController {
@Autowired
ProviderService providerService;
@RequestMapping("/consumer/provider")
@SentinelResource(value = "consumer",
blockHandlerClass = {BlockHandlerService.class},blockHandler = "provider",
fallbackClass ={FallbackClassService.class},fallback = "provider")
public String consumer(){
String provider = providerService.provider();
//int i = 1/0;
return provider;
}
}
6、测试
1. 启动两个服务提供者(生产者):
怎么创建生产者可以参考
:spring cloud Alibaba——01 Nacos
2. 启动消费者