Spring Cloud Alibaba:将 Sentinel 熔断限流规则持久化到 Nacos 配置中心

1,498 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情


通过前面:

服务容错的必要性与Spring Cloud Alibaba Sentinel 限流配置实战

Spring Cloud Alibaba Sentinel 熔断降级策略实战

两篇关于如何使用 Sentinel 的介绍,我们已经知道如何从 Sentinel 控制台配置限流、熔断规则,但是实际操作的过程中你会发现,每次项目重启后,配置的限流规则都没有了!

这是因为,在 Sentinel DashBoard 上配置的规则只存在缓存中,当项目重启,这些规则自然就消失了。

实际生产环境中,我们是不允许这种情况存在的,那么如何进行 Sentinel 配置规则的持久化呢?Sentinel 提供多种不同的数据源来持久化规则配置,包括 FileRedisNacosZooKeeper 等。

前面我已经整过 Nacos数据持久化 相关的内容,详见:

Nacos的数据持久化

本文将演示如何持久化 Sentinel 规则到 Nacos 中。

Nacos 配置中心配置持久化规则

将 Sentinel 规则持久化到 Nacos 中保存,只要请求了某个微服务的资源,Sentinel 控制台的规则就能感应到,同时只要 Nacos 里面的配置不删除,针对该微服务上资源的 Sentinel 流控规则就持续有效。

只要实现了 Nacos 和 Sentinel 之间的通信,就能从持久化的 Nacos 中获取 Sentinel 流控规则。

Tips: 在 Nacos 控制台上修改流控制,虽然可以同步到 Sentinel Dashboard,但是 Nacos 此时应该作为一个流控规则的持久化平台。正常操作过程应该是我们在 Sentinel Dashboard 上修改流控规则后同步到 Nacos ,但是目前并不能从 Sentinel Dashboard 配置完之后主动同步到 Nacos —— 需要我们在 Nacos 配置中心配置限流/熔断等 Sentinel 规则。

集成到 Spring Cloud Alibaba微服务项目

沿用前面文章的案例,在微服务项目 cloud-sentinel-service 中,增加内容:将 Sentinel 流控规则放到 Nacos 配置中心进行持久化。

在 Nacos 中配置流控规则

进入到 Nacos 控制台,进入到 配置管理 新建一个配置文件:

接下来输入 dataId , 文件类型选择 json

然后点击发布即可。

这里需要说明一下,具体的规则怎么配,配置项的含义说明:

流量控制规则(FlowRule)

  • resource :资源名,资源名是限流规则的作用对象,比如请求资源 getUser
  • grade :限流阈值类型,QPS 或线程数模式。0表示线程数,1表示QPS。默认为1,即 QPS 模式
  • count :限流阈值。比如值为2表示1秒超过2个请求就限流。
  • strategy :流控模式:直接、链路、关联,默认 直接 。0表示直接,1表示关联,2表示链路。
  • controlBehavior :流控效果(直接拒绝 / 排队等待 / 慢启动模式),0表示快速失败,1表示Warm Up,2表示排队等待。
  • limitApp :流控针对的调用来源。默认就是 default ,代表不区分调用来源.

熔断降级规则 (DegradeRule)

  • resource :资源名,资源名是限流规则的作用对象,比如请求资源 getUser
  • grade :熔断策略,支持慢调用比例/异常比例/异常数策略。1:慢调用比例,2:异常比例,3:异常数。默认为1,慢调用比例。
  • count :慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值。
  • timeWindow :熔断时长,单位为秒。
  • minRequestAmount :熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断。默认为 5 。
  • statIntervalMs :统计时长(单位为 ms),如 60*1000 代表分钟级。默认为 1000 ms。
  • slowRatioThreshold :慢调用比例阈值,仅慢调用比例模式有效

Tip:同一个资源可以同时有多个降级规则。

Spring Cloud Alibaba 微服务项目中设置 Sentinel 数据源

首先,需要引入相关依赖包:

<!-- 引入 Sentinel 数据源 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
</dependency>
<!-- Sentinel数据源之 Nacos -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

然后,配置 application.yml

server:
  port: 7072

spring:
  application:
    name: cloud-sentinel-service

  cloud:
    nacos:
      discovery:
        server-addr: 192.168.242.112:81
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
      # https://github.com/alibaba/Sentinel/issues/1213
      web-context-unify: false
      datasource:
        nacos:
          nacos:
            serverAddr: 192.168.242.112:81
            groupId: DEFAULT_GROUP
            dataId: sentinelFlowRule.json
            ruleType: flow

management:
  endpoints:
    web:
      exposure:
        include: '*'

增加了配置项: spring.cloud.sentinel.datasource ,配置项指定了数据源为 Nacos,并且配置 Nacos 的 IP 地址以及 dataId 等。

根据前面在 Nacos 配置的流控规则:

[
  {
    "resource": "getUser",
    "limitApp": "default",
    "grade": 1,
    "count": 2,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  },
  {
    "resource": "getOrder",
    "limitApp": "default",
    "grade": 1,
    "count": 2,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  }
]

该规则说明:

资源 getUsergetOrder 的限流类型是 1:QPS,限流阈值时2,即当1秒大于2个请求就进行限流,限流策略时直接,流控效果是直接拒绝。

下面在 Controller 中写两个资源:

@GetMapping("/getUser")
@SentinelResource("getUser")
public String getUser() {
    return "getUser success!";
}

@GetMapping("/getOrder")
@SentinelResource("getOrder")
public String getOrder() {
    return "getOrder success!";
}

OK,至此就可以验证了。

验证限流规则

当我们访问 /getUser/getOrder 后,Sentinel DashBoard 会自动出现流控规则:

这和在 Nacos 中配置的规则一致。

根据限流规则,访问请求资源测试:

当正常访问时:

快速刷新应该会限流:

这样就表示限流了,规则生效!

PS:这样的限流直接返回了500错误,这里我先填一个坑,下次再说如何优雅的进行限流和降级。

小结

生产环境中,我们可以将 Sentinel 限流规则、熔断规则等配置到 Nacos 中进行持久化。

规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,使用 Nacos 配置中心有更好的实时性和一致性保证。

点个赞再走吧~