spring cloud Alibaba——02 Sentinel

目录标题

    • 一、安装Sentinel
    • 二、Sentinel入门案例
      • 1、导入pom
      • 2、改yml
      • 3、主启动类
      • 4、测试类
      • 5、设置断路规则(核心)
    • 三、配置断路规则
      • 1、断路规则配置分类
      • 2、规则的种类
        • 2.1、流量控制规则 (FlowRule)
        • 2.2、熔断降级规则 (DegradeRule)
        • 2.3、系统保护规则 (SystemRule)
        • 2.4、Sentinel热点key(`常用`)
    • 四、注解@SentinelResource
      • 注意:@SentinelResource需要配合@RestController(@Controller和@ResponseBody)使用,也就是。我们控制器只能返回数据,不能返回视图。不然,降级处理方法将会不起作用。
      • 1、value
      • 2、entryType:
      • 3、blockHandler / blockHandlerClass: (违反断路规则触发)
      • 4、fallback:(请求异常触发)
      • 5、defaultFallback(since 1.6.0):
      • 6、exceptionsToIgnore(since 1.6.0):
    • 五、持久化Sentinel断路规则
      • 3、到nacos配置一个断路规则
      • 4、通过注解绑定请求
      • 5、如何编写配置
    • 六、Sentinel整合负载均衡
      • 1、导入pom
      • 2、改yml
      • 3、主启动类
      • 4、业务层
      • 5、控制层
      • 6、测试

如果不具备nacos的知识,推荐先看spring cloud Alibaba——01 Nacos

一、安装Sentinel

  1. 下载地址:https://github.com/alibaba/Sentinel/releases
  2. 终端运行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’
  1. 访问:http://localhost:8080/
    默认登录账号、密码:sentinel、sentinel
  2. 成功页面
    spring cloud Alibaba——02 Sentinel_第1张图片

注意:Sentinel使用的是懒加载。当被监控的请求,第一次访问后才会被Sentinel记录下来。

二、Sentinel入门案例

官方文档:https://sentinelguard.io/zh-cn/docs/flow-control.html

Sentinel的使用可以分为三步:

  1. 定义资源
  2. 定义规则
  3. 检验规则是否生效

我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。使用 Sentinel 来进行资源保护,主要分为几个步骤:
先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。

1、导入pom

注意:本文的所有pom依赖的版本控制,都是基于父项目的。通过父项目,统一管理版本,避免依赖冲突。

父项目pom依赖:

<dependencyManagement>
    <dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-dependenciesartifactId>
            <version>2.2.2.RELEASEversion>
            <type>pomtype>
            <scope>importscope>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-dependenciesartifactId>
            <version>Hoxton.SR1version>
            <type>pomtype>
            <scope>importscope>
        dependency>
        
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-alibaba-dependenciesartifactId>
            <version>2.1.0.RELEASEversion>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>

子项目依赖:

<dependencies>
        
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibaba.cspgroupId>
            <artifactId>sentinel-datasource-nacosartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
            <version>2.1.1.RELEASEversion>
        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 用户界面设置即可
比如:设置一个限流规则:
spring cloud Alibaba——02 Sentinel_第2张图片
spring cloud Alibaba——02 Sentinel_第3张图片

spring cloud Alibaba——02 Sentinel_第4张图片
spring cloud Alibaba——02 Sentinel_第5张图片
限流规则添加成功
在这里插入图片描述
再次访问:http://localhost:8001//testA
连续刷新当每秒请求超过1次时就会触发服务降级。

spring cloud Alibaba——02 Sentinel_第6张图片

三、配置断路规则

上面的入门案例我们也就配置过流量控制了。我们如何配置其他的断路规则呢?
sentinel为我们提供了以下的断路配置规则:
spring cloud Alibaba——02 Sentinel_第7张图片

1、断路规则配置分类

其实sentinel断路规则按照配置方式可以配置两种。

  1. 一种是入门案例中的配置方式,在sentinel提供的用户界面就行配置。(推荐使用
    这种方式会随着服务(这个服务是受监控的服务)的关闭而丢失配置信息。因此需要将这些规则配置持久化 后面会讲如何实现持久化。
  2. 一种是通过代码配置。(不推荐
    这种方式是可以实现持久化的,但是会增加代码的耦合度,并且实现比较麻烦。
    比如:
/**
 * 定义资源
 * */
@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)

spring cloud Alibaba——02 Sentinel_第8张图片
下面我们为testA添加一个流控规则:
spring cloud Alibaba——02 Sentinel_第9张图片
spring cloud Alibaba——02 Sentinel_第10张图片

  • 资源名:唯一名称,有两种形式的值。方式一:请求路径的格式(资源名字前面有斜杠/),比如:/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的线程数达到阈值的时候,进行限流。(选择线程数后,单机阈值的值就表示,同一时间同时访问的线程数为多少个,也就是支持多少个用户同时访问这个请求
  • 是否集群:不需要集群。

    • 单机均摊 : 以单机为单位,单机请求数达到阈值后,集群限流
    • 总体阈值 :以集群为单位,集群请求数达到阈值后,集群限流
  • 流控模式:

    • 直接:请求达到限流条件时,直接限流
    • 关联:当关联的资源B达到阈值时,就限流自己A。
      举例 :用户 请求 A 调用(消费)B 。当B限流时(服务不可用),那么A也会限流自己。
    • 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【API级别的针对来源】。
      举例 :A->B->C 当 入口资源A限流时限流自己
  • 流控效果:

    • 快速失败:直接失败,抛异常。
    • Warm up:根据Code Factor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值。
    • 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效。

2.2、熔断降级规则 (DegradeRule)

spring cloud Alibaba——02 Sentinel_第11张图片
spring cloud Alibaba——02 Sentinel_第12张图片
spring cloud Alibaba——02 Sentinel_第13张图片
spring cloud Alibaba——02 Sentinel_第14张图片

spring cloud Alibaba——02 Sentinel_第15张图片

2.3、系统保护规则 (SystemRule)

spring cloud Alibaba——02 Sentinel_第16张图片
spring cloud Alibaba——02 Sentinel_第17张图片

2.4、Sentinel热点key(常用

spring cloud Alibaba——02 Sentinel_第18张图片

注意:热点规则(比较常用),可以理解为给请求的进一步定制断路规则
spring cloud Alibaba——02 Sentinel_第19张图片
举例:

spring cloud Alibaba——02 Sentinel_第20张图片

@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这个注解有以下属性:
spring cloud Alibaba——02 Sentinel_第21张图片

1、value

value属性用来指定资源名

@SentinelResource(value = "testA")

spring cloud Alibaba——02 Sentinel_第22张图片

2、entryType:

entry 类型,可选项(默认为 EntryType.OUT)

3、blockHandler / blockHandlerClass: (违反断路规则触发)

blockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockExceptionblockHandler 函数默认需要和原方法在同一个类中若希望使用其他类的函数,则可以指定 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
Push-based: ZooKeeper, Redis, Nacos, Apollo, etcd
`注意:下面这种方式是通过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
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配置一个断路规则

spring cloud Alibaba——02 Sentinel_第23张图片

[
{
    "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、如何编写配置

比如:我们编写一个热点规则。
通过官网我们可以获取到对应的属性名:官网

spring cloud Alibaba——02 Sentinel_第24张图片
spring cloud Alibaba——02 Sentinel_第25张图片
注意:使用时把注释去掉。

  • 流控规则
    根据实际的需要改变减少对应的参数即可

    [
      {
        // 资源名
        "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整合负载均衡

项目结构
spring cloud Alibaba——02 Sentinel_第26张图片

1、导入pom

<dependencies>
    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-actuatorartifactId>
    dependency>
    
    <dependency>
        <groupId>com.alibaba.cspgroupId>
        <artifactId>sentinel-datasource-nacosartifactId>
    dependency>
    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
        <version>2.1.1.RELEASEversion>
    dependency>

    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-openfeignartifactId>
    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配置中心创建远程配置文件:
spring cloud Alibaba——02 Sentinel_第27张图片

[{
    "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. 启动消费者
spring cloud Alibaba——02 Sentinel_第28张图片
spring cloud Alibaba——02 Sentinel_第29张图片
spring cloud Alibaba——02 Sentinel_第30张图片

你可能感兴趣的:(spring,cloud,alibaba,spring,spring,boot,java,spring,cloud,alibaba)