草庐IT

【springcloud 微服务】Spring Cloud Alibaba整合Sentinel详解

逆风飞翔的小叔 2023-04-11 原文

目录

一、前言

二、环境准备

2.1 部署sentinel管控台

2.1.1 官网下载sentinel的jar包

2.1.2 启动控制台

 2.1.3 访问控制台

2.2 整合springcloud-alibaba

2.2.1 引入相关依赖

2.2.2 修改配置文件

2.2.3 增加一个测试接口

2.2.4 接口测试

三、sentinel 流控规则使用

3.1 实时监控

3.2  簇点链路

3.3  流控规则概述

3.3.1 流量控制原理

3.3.2 流量控制常用场景

3.3.3 流控规则的详细参数

3.4  常用流控规则

3.4.1 QPS限流

 3.4.2 自定义限流返回结果

3.4.3 并发线程数限流

3.4.4 自定义异常

3.5 流控模式

3.5.1 流控模式概述

3.5.2 流控模式 —— 直接

3.5.3 流控模式 —— 关联

3.5.4 流控模式 —— 链路

3.6 流控效果

3.6.1 快速失败

3.6.2 Warm Up

3.6.3 排队等待

四、sentinel 降级规则

4.1 降级规则概述

4.1.1 为什么需要降级

4.1.2 降级与隔离

4.1.3 熔断后的处理逻辑

4.2 熔断策略

4.2.1 慢调用比例

4.2.2 异常比例

五、整合openfeign

5.1 服务提供方

5.2 服务消费方

5.2.1 添加pom依赖

5.2.2 添加配置文件

5.2.3 添加feign接口

5.2.4 提供降级的类

5.2.5 添加测试接口

5.2.6 接口测试与验证

六、热点参数限流

6.1 何为热点参数

6.1.1 使用场景

6.2 热点参数使用

6.2.1 新增一个测试接口

6.2.2 dashboard 如下配置

6.2.3 测试验证

6.3 系统规则使用

6.3.1 系统规则来源

6.3.2 sentinel系统规则概述

6.3.3 sentinel控制台配置

七、Sentinel配置规则持久化

7.1 三种规则持久化模式

7.1.1 原始模式

7.1.2 pull模式

7.1.3 push模式 

7.2  整合nacos规则持久化

7.2.1 引入依赖

7.2.2 配置文件

7.2.3 naocos新增一个配置文件

7.2.4 请求接口

7.2.5 重启服务

八、写在文末


一、前言

从前面的学习了解到sentinel是springcloud alibaba微服务生态下的一个重要的流量治理组件,在微服务架构中占据着非常重要的地位,本篇将详细介绍下springcloud alibaba中如何整合sentinel,以及结合sentinel控制台聊聊其深入的使用。

二、环境准备

2.1 部署sentinel管控台

git下载地址下载地址:

2.1.1 官网下载sentinel的jar包

注意版本的匹配

2.1.2 启动控制台

由于是一个springboot的服务jar包,直接使用java -jar命令即可启动

 2.1.3 访问控制台

启动成功后,默认端口是8080,浏览器直接:localhost:8080,默认登录账户名和密码为:sentinel /sentinel,登录之后看到下面界面,首次进入为空页面;

2.2 整合springcloud-alibaba

sentinel与springcloud-alibaba整合比较简单,按照下面的几步操作即可。

2.2.1 引入相关依赖

导入以下基础依赖即可

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel</artifactId>
        </dependency>

    </dependencies>

2.2.2 修改配置文件

这里暂时没有对接其他的外部依赖,只需配置与sentinel的控制台的连接信息

server:
  port: 8032

spring:
  application:
    name: sentinel-order
  #注册中心使用nacos
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080

2.2.3 增加一个测试接口

这里添加一个测试接口,用于接下来的各种流控规则的测试

@RestController
@RequestMapping("/order")
public class OrderController {

    @GetMapping("/add")
    public String add(){
        System.out.println("准备下单");
        return "hello " ;
    }

}

2.2.4 接口测试

启动工程后,浏览器反复调用几次接口:localhost:8032/order/add,此后在sentinel的控制台就能看到如下相关的监控信息了;

三、sentinel 流控规则使用

通过上面的准备,在sentinel控制台左侧呈现出了详细的规则配置菜单,接下来,结合代码分别聊聊各种配置的详细使用。

3.1 实时监控

监控接口的通过的QPS和拒绝的QPS,比如我们反复刷以下add接口,就能在监控中左侧看到该接口一段时间内的调用频率趋势图,右侧的表格则更直观的记录了在具体的时间点内QPS的通过和拒绝情况;

3.2  簇点链路

显示微服务的所有被监控的API资源信息,比如上面的add接口在图中就呈现了出来,同时这个页面也是后续设置API接口流控规则的主要入口。

3.3  流控规则概述

还记得在上一篇中,我们通过使用sentinel的SDK演示了各种流控规则的使用,有了sentinel的控制台之后,就变得更简单了,接下来就来详细说明下如何使用控制台的各种流控规则的配置。

3.3.1 流量控制原理

其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

3.3.2 流量控制常用场景

  • 应对洪峰流量,比如秒杀,大促,下单回流等;
  • 付费系统,根据使用流量付费;
  • API Gateway,精准控制API流量;
  • 其他应用,探测应用中运行慢的模块,进行控制;

3.3.3 流控规则的详细参数

同一个资源可以设置多条限流规则,FlowSlot 会对该资源的所有限流规则依次遍历,直到有规则触发限流或者所有规则遍历完毕,一条限流规则主要由下面几个因素组成,我们可以组合这些元素来实现不同的限流效果;

Field
说明
默认值
resource
资源名,资源名是限流规则的作用对象
count
限流阈值
grade
限流阈值类型,QPS 模式(1)或并发线程数模式(0)
QPS 模式
limitApp
流控针对的调用来源
default ,代表不区分调用来源
strategy
调用关系限流策略:直接、链路、关联
根据资源本身(直接)
controlBehavior
流控效果(直接拒绝/WarmUp/匀速+排队等
待),不支持按调用关系限流
直接拒绝
clusterMode
是否集群限流

流控规则详细说明:git地址

3.4  常用流控规则

3.4.1 QPS限流

QPS(Query Per Second)

每秒请求数,就是说服务器在一秒的时间内处理了多少个请求。

给order接口设置一个流控规则,现在每秒的请求数量上限为2;

设置完成后,界面再次快速访问时如果超过了QPS设置的阈值,将会看到下面的效果,说明配置规则生效了;

 3.4.2 自定义限流返回结果

上面的规则生效后,快速刷接口时返回的提示信息是sentinel默认的一串值,如果要自定义返回信息,只需要通过@SentinelResource注解进行自定义返回值即可,如下:

    @GetMapping("/add")
    @SentinelResource(value = "add",blockHandler = "addBlockHandler")
    public String add(){
        System.out.println("准备下单");
        return "hello " ;
    }

    public String addBlockHandler(BlockException b){
        return "add 接口被流控了";
    }

然后重新启动工程,再次快速刷接口时将会看到下面的效果;

3.4.3 并发线程数限流

并发线程数控制用于保护业务线程池不被慢调用耗尽。

例如,当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加,对于调用者来说,意味着吞吐量下降和更多的线程数占用,极端情况下甚至导致线程池耗尽。为应对太多线程占用的情况,业内有使用隔离的方案,比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢(线程池隔离)。这种隔离方案虽然隔离性比较好,但是代价就是线程数目太多,线程上下文切换的 overhead 比较大,特别是对低延时的调用有比较大的影响。

Sentinel 并发控制不负责创建和管理线程池,而是简单统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求会被立即拒绝,效果类似于信号量隔离。并发数控制通常在调用端进行配置。

新增一个接口

为了模拟出效果,给接口添加一个休眠时间,表示当前接口执行速度较慢,这样的话,当设置并发线程数时,如果第一个请求没有处理完,下一个请求过来时只能排队等待;

    @GetMapping("/flow/thread")
    @SentinelResource(value = "flowThread",blockHandler = "flowThreadBlockHandler")
    public String flowThread(){
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("准备flowThread");
        return "flowThread " ;
    }

    public String flowThreadBlockHandler(BlockException b){
        return "flowThread 接口被流控了";
    }

界面上为该接口配置如下流控规则,这里设置为1

保存之后,第一次请求该接口,此时,再开一个窗口再次请求该接口,将会看到如下的效果;

3.4.4 自定义异常

为了统一处理流控接口的异常,可以通过自定义全局异常类,然后在需要使用的地方引用即可

public class MyBlockException  {

    public static Map handleException(BlockException e){
        Map<String,Object> resultMap = new HashMap<>();
        if(e instanceof FlowException){
            resultMap.put("code",100);
            resultMap.put("msg","被限流了:" + e.getMessage());
        } else if (e instanceof DegradeException) {
            resultMap.put("code",101);
            resultMap.put("msg","服务被降级了:" + e.getMessage());
        } else if (e instanceof ParamFlowException) {
            resultMap.put("code",102);
            resultMap.put("msg","热点参数限流:" + e.getMessage());
        } else if (e instanceof SystemBlockException) {
            resultMap.put("code",103);
            resultMap.put("msg","触发系统保护规则:" + e.getMessage());
        } else if (e instanceof AuthorityException){
            resultMap.put("code",104);
            resultMap.put("msg","授权规则不通过:" + e.getMessage());
        }
        return resultMap;
    }

}

再在需要限流的接口上通过 @SentinelResource 引用即可

    @GetMapping("/add")
    //@SentinelResource(value = "add",blockHandler = "addBlockHandler")
    @SentinelResource(value = "add",
            blockHandlerClass = MyBlockException.class,
            blockHandler = "handleException")
    public Map<String, Object> add() {
        System.out.println("准备下单");
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("code", 200);
        resultMap.put("msg", "下单成功");
        return resultMap;
    }

通过sentinel控制台配置一下限流规则后,再次测试以下add接口

3.5 流控模式

在流控规则下面点开高级选项,可以看到流控模式这一选项,相当于是限流规则的补充;

3.5.1 流控模式概述

1)基于调用关系的流量控制,调用关系包括调用方、被调用方;

2)一个方法可能会调用其它方法,形成一个调用链路的层次 关系;

从控制台可以看到提供了3钟方式,分别为:直接,关联和链路。

3.5.2 流控模式 —— 直接

资源调用达到设置的阈值后直接被流控抛出异常

比如上文中设置的QPS限流,默认情况下即为直接的效果

3.5.3 流控模式 —— 关联

当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联,设置了关联之后,当一个资源被限流后,这个关联的资源也将会受到影响

比如有下面两个接口,一个生成订单的接口,一个查询订单的接口,假设生成订单接口会影响到查询订单,即它们两个之间存在关联;

    @GetMapping("/create")
    public String createOrder(){
        System.out.println("生成订单");
        return "生成订单";
    }

    @GetMapping("/get")
    public String getOrder(){
        System.out.println("查询订单");
        return "查询订单";
    }

在sentinel控制台做如下设置

3.5.4 流控模式 —— 链路

根据调用链路入口限流

比如当微服务集群中,某个微服务调用了一系列其他的微服务时,相互之间可能就构成了一棵调用树,其根节点就是起始调用的那个接口,比如:这棵树的根节点是一个名字为 getUser 的虚拟节点,调用链的入口都是这个虚节点的子节点

getUser

/  \

/  \

/ order / test1  / order / test2

上图中来自入口 /order/test1 和 /order/test2的请求都调用到了资源 getUser,Sentinel 允许只根据某个入口的统计信息对 资源限流。

新增两个接口

    @Autowired
    private UserService userService;

    @GetMapping("/user1")
    public String user1(){
        return userService.getUser();
    }

    @GetMapping("/user2")
    public String user2(){
        return userService.getUser();
    }

业务实现

@Service
public class UserService {

    @SentinelResource(value = "getUser")
    public String getUser() {
        return "查询用户";
    }
}

sentinel控制台设置链路,仅对来源为user2的接口进行限流

3.6 流控效果

 流控效果即资源被流控之后展示出来的效果,主要包括3种:

  • 快速失败;
  • Warm up;
  • 排队等待;

3.6.1 快速失败

默认的流控方式,上面展示的大多数流控后的效果就是快速识别,抛出流控异常,这里不再演示。

当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。

3.6.2 Warm Up

即预热/冷启动方式。

当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过Warm Up的方式,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

sentinel控制台如下设置

测试发现,当接口刷的频率达到一定值时,将会看到被限流的效果,但不是立马被限流,而是能明显看到经历了一个过程;

也可以通过实时监控效果进一步确认当前接口的访问频率

3.6.3 排队等待

这种方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,底层实现对应的是漏桶算法。

这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。

在sentinel的控制台做如下配置

通过压测工具访问接口,一段时间内当请求的QPS超过5个时,界面上会出现短暂的等待效果;

通过实时监控效果,也可以看出请求时间段内的QPS情况

四、sentinel 降级规则

4.1 降级规则概述

4.1.1 为什么需要降级

除了流控以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。

我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。

4.1.2 降级与隔离

服务的熔断、降级与隔离是保护服务自身的一种有效手段,通常在consumer端组合使用,主要实施手段有:

1)并发控制(信号量隔离);

2)基于慢调用比例熔断;

3)基于异常比例熔断;

4.1.3 熔断后的处理逻辑

当消费端调用的服务进行熔断后,通常可采用下面的处理逻辑:

1)提供fallback结果(服务降级);

2)返回错误result;

3)读取缓存(降低DB访问量);

熔断降级规则( DegradeRule )包含下面几个重要的属性
Field
说明
默认值
resource
资源名,即规则的作用对象
grade
熔断策略,支持慢调用比例/异常比例/异常数策略
慢调用比例
count
慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
timeWindow
熔断时长,单位为 s
minRequestAmount
熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入)
5
statIntervalMs
统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入)
1000 ms
slowRatioThreshold
慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)

4.2 熔断策略

4.2.1 慢调用比例

选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。

当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF­OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断

 新增一个接口,在该接口中处理需要3秒

    @GetMapping("/flow/thread")
    public String flowThread() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("准备flowThread");
        return "flowThread ";
    }

在sentinel控制台做如下配置,简单说下几个关键参数含义:

  • 最大RT,本次规则容忍的请求接口最大处理时长,为毫秒,比如这里设置的不能超过1秒;
  • 最小请求数,即统计的时间区间内最小的请求数量的下限不得低于这个数;
  • 熔断时长,触发熔断之后的持续时长;
  • 比例阈值,10次请求中当发生多少比例请求的慢调用时触发熔断规则;

 

保存完毕后,可以直接在浏览器进行模拟调用,当调用的次数和频率符合了规则时,将看到下面的效果;

 

 同时可以从实时监控效果可以看到QPS的数据;

4.2.2 异常比例

当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。

经过熔断时长后熔断器会进入探测恢复状态(HALF­OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% ­ 100%。

新增一个带有异常的接口

    @GetMapping("/err")
    public String err() {
        int a = 1/0;
        return "err ";
    }

sentinel做如下配置

浏览器访问接口,当满足规则中的条件时将会触发熔断,出现下面的效果;

五、整合openfeign

在使用openfeign进行服务调用时,对于客户端来说,被调用的服务接口出现异常时,为了消费端的服务接口不被拖垮,通常来说也需要做服务的熔断降级处理,以提升自身的稳定性,此时就可以考虑接入sentinel,接下来看看如何在openfeign中使用sentinel。

5.1 服务提供方

准备两个工程,第一个工程作为服务提供方,使用之前的一个扣减库存的工程,其中有一个异常接口

    @GetMapping("/reduct2")
    public String reduct2() {
        int a=1/0;
        return "扣减库存 : reduct2";
    }

5.2 服务消费方

工程结构如下

5.2.1 添加pom依赖

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--nacos-discovery 注册中心-服务发现与注册-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel</artifactId>
        </dependency>

    </dependencies>

5.2.2 添加配置文件

server:
  port: 8040

spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #服务注册中心地址
      #config:
        #server-addr: localhost:8848 #配置中心地址
    sentinel:
      transport:
        dashboard: localhost:8080


feign:
  sentinel:
    enabled: true

5.2.3 添加feign接口

@FeignClient(name = "stock-service",path = "/stock",fallback = FallBackService.class)
public interface StockFeignService {

    @GetMapping("/reduct")
    public String reduct();

    @GetMapping("/reduct2")
    public String reduct2();

    @GetMapping("/get")
    public String get(@RequestParam("id") Integer id);
}

5.2.4 提供降级的类

@Component
public class FallBackService implements StockFeignService{

    @Override
    public String reduct() {
        return null;
    }

    @Override
    public String reduct2() {
        return "服务被降级了";
    }

    @Override
    public String get(Integer id) {
        return null;
    }
}

5.2.5 添加测试接口

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private StockFeignService stockFeignService;

    //localhost:8083/order/add
    @GetMapping("/add")
    public String add(){
        System.out.println("下单成功");
        String reduct = stockFeignService.reduct2();
        return "add order  :" + reduct;
    }

}

5.2.6 接口测试与验证

启动nacos服务,启动两个工程,浏览器调用:localhost:8040/order/add,看到下面的效果

六、热点参数限流

6.1 何为热点参数

热点参数也可以理解为热点接口,即在一个系统中,那些被高频调用的接口以及某参数对应的接口,比如根据商品ID获取商品详情这样的接口在一个电商系统中一定是高频被调用的接口。

很多时候我们希望统计某个热点数据中访问频次最高的数据,并对其访问进行限制,以免被该来源的IP或应用占用太多的服务资源拖慢了整个系统的效率。

6.1.1 使用场景

比如:热点商品的访问(访问控制),识别热点参数接口之后对来源用户/app/IP进行限制,避免防刷;

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

6.2 热点参数使用

6.2.1 新增一个测试接口

注意点

1)热点规则需要使用@SentinelResource("resourceName")注解,否则不生效;

2)参数必须是7种基本数据类型才会生效

    @GetMapping("/get/{id}")
    @SentinelResource(value = "getById",blockHandler = "hotBlockHandler")
    public String getById(@PathVariable("id") Integer id){
        System.out.println("正常访问");
        return "正常访问" ;
    }

    public String hotBlockHandler(@PathVariable("id") Integer id,BlockException e){
        return "热点异常处理结果" ;
    }

 6.2.2 dashboard 如下配置

新增完成后,在热点规则列表就有了一个数据,继续编辑

6.2.3 测试验证

请求时设置参数为1 ,每秒1次,可以正常响应结果

每秒超过1次时,触发热点规则降级

6.3 系统规则使用

6.3.1 系统规则来源

在真实的生产环境下,对一个复杂的系统来说,引起系统故障或者突然崩溃的因素有很多,比如:

  • 对系统容量评估不到位,导致个别大流量的接口没有配置限流规则或者配置不合理,由于来不及处理而崩溃;
  • 机器突发CPU飙高,但是短期内很难定位到原因导致系统挂掉;
  • 集群中其中一台机器挂掉,导致流量被转移到其他机器上,另外的机器被打满而引起服务雪崩或宕机;

希望有个全局的兜底防护,即使一开始缺少容量评估也有一定的保护机制。简单来说就是,结合系统的指标和服务容量,能够自适应动态调整流量。

6.3.2 sentinel系统规则概述

Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

Load 自适应

仅对 LinuxUnix­like 机器生效,是系统的 load1 作为启发指标,进行自适应系统保护。当系统load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。

CPU usage

当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0­1.0),比较灵敏。

平均 RT 

当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒 

并发线程数

当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护 

入口QPS

当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护 

6.3.3 sentinel控制台配置

在控制台上,提供了多种系统保护规则,这里以其中的某一种为例进行说明,比如下面设置“入口QPS”,这里设置为1

 

删除之前配置的其他接口配置规则,快速刷新接口时,可以看到下面的效果,说明这种全局配置规则生效了。

七、Sentinel配置规则持久化

在上面的操作中可以发现一个比较大的问题就是,一旦当工程重启,或者sentinel服务重启之后,之前界面上配置的规则就丢失了,这个并不奇怪,因为默认情况下,这些规则是动态的存储在内存中的,这在线上环境是肯定不允许的,因此为了安全起见,需要将sentine的配置规则进行持久化存储。

关于sentinel的规则持久化,官方主要提供了3种模式,分别做一一概述

7.1 三种规则持久化模式

7.1.1 原始模式

API 将规则推送至客户端并直接更新到内存中,扩展写数据源(WritableDataSource),其优点就是简单无需任何依赖,缺点也很明显,重启就丢失。

7.1.2 pull模式

扩展写数据源(WritableDataSource),客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件等,其优点就是简单无需任何依赖,缺点是不能保证一致性,实时性得不到保障,拉取过于频繁时可能存在性能问题。

pull 模式的数据源(如本地文件、RDBMS 等)一般是可写入的。使用时需要在客户端注册数据源:将对应的读数据源注册至对应的 RuleManager,将写数据源注册至 transport的WritableDataSourceRegistry 中。

7.1.3 push模式 

扩展读数据源(ReadableDataSource),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源,其优点是,规则持久化且能保持一致性,快捷,但是需要引入第三方依赖。

生产环境下一般更常用的是 push 模式的数据源。对于 push 模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不应由 Sentinel 客户端进行,而应该经控
制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是 配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel,而不是经 Sentinel 数据源推送至配置中心。这样的流程就非常清晰了:

7.2  整合nacos规则持久化

7.2.1 引入依赖

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

7.2.2 配置文件

下面贴出完整的配置文件内容

server:
  port: 8040

spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #服务注册中心地址
      #config:
        #server-addr: localhost:8848 #配置中心地址
    sentinel:
      transport:
        dashboard: localhost:8080
      datasource:
          ds1:
            nacos:
              server-addr: localhost:8848
              dataId: order-flow-rules
              groupId: DEFAULT_GROUP
              data-type: json
              rule-type: flow

feign:
  sentinel:
    enabled: true

7.2.3 naocos新增一个配置文件

配置文件的名称即为yaml中的dataId对应的名称,选择json格式,内容如下:

[
    {
    "resource": "/testFlow",
    "limitApp":"default",
    "grade":1,
    "count":1,
    "strategy":0,
    "controlBehavior":0,
    "clusterMode":false
    }
]

关于参数解释

resource:资源名称
limitApp:来源应用
grade:阀值类型,0:线程数,1:QPS
count:单机阀值
strategy:流控模式,0:直接,1:关联,2:链路
controlBehavior:流控效果,0:快速失败,1:warmUp,2:排队等待
clusterMode:是否集群

7.2.4 请求接口

此时还未登录dashboard的情况下,快速刷接口时,可以看到如下效果,说明此时从nacos中读取到了配置规则

 此时再看dashboard,可以看到这里针对该接口多了一个流控规则

7.2.5 重启服务

重启服务,稍等一会之后,再次刷接口,再次进入dashboard进行查看流控规则,发现依然能够加载到之前从nacos中的流控规则,说明持久化规则生效了。

八、写在文末

本文通过较大的篇幅,全方位讲述了sentinel的限流、熔断降级等规则的使用,以及如何整合springcloud进行跨服务访问使用,由于sentinel涉及到的点比较多,需要投入较多的时间和精力去研究,这对于后续在生产环境中合理使用sentinel的功能时也是一个很好的储备。

 

有关【springcloud 微服务】Spring Cloud Alibaba整合Sentinel详解的更多相关文章

  1. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  2. 物联网MQTT协议详解 - 2

    一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su

  3. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

  4. 【云原生】SpringCloud-Spring Boot Starter使用测试 - 2

    目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一

  5. 【详解】Docker安装Elasticsearch7.16.1集群 - 2

    开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建

  6. 【Elasticsearch基础】Elasticsearch索引、文档以及映射操作详解 - 2

    文章目录概念索引相关操作创建索引更新副本查看索引删除索引索引的打开与关闭收缩索引索引别名查询索引别名文档相关操作新建文档查询文档更新文档删除文档映射相关操作查询文档映射创建静态映射创建索引并添加映射概念es中有三个概念要清楚,分别为索引、映射和文档(不用死记硬背,大概有个印象就可以)索引可理解为MySQL数据库;映射可理解为MySQL的表结构;文档可理解为MySQL表中的每行数据静态映射和动态映射上面已经介绍了,映射可理解为MySQL的表结构,在MySQL中,向表中插入数据是需要先创建表结构的;但在es中不必这样,可以直接插入文档,es可以根据插入的文档(数据),动态的创建映射(表结构),这就

  7. 最强Http缓存策略之强缓存和协商缓存的详解与应用实例 - 2

    HTTP缓存是指浏览器或者代理服务器将已经请求过的资源保存到本地,以便下次请求时能够直接从缓存中获取资源,从而减少网络请求次数,提高网页的加载速度和用户体验。缓存分为强缓存和协商缓存两种模式。一.强缓存强缓存是指浏览器直接从本地缓存中获取资源,而不需要向web服务器发出网络请求。这是因为浏览器在第一次请求资源时,服务器会在响应头中添加相关缓存的响应头,以表明该资源的缓存策略。常见的强缓存响应头如下所述:Cache-ControlCache-Control响应头是用于控制强制缓存和协商缓存的缓存策略。该响应头中的指令如下:max-age:指定该资源在本地缓存的最长有效时间,以秒为单位。例如:Ca

  8. IDEA 2022 创建 Spring Boot 项目详解 - 2

    如何用IDEA2022创建并初始化一个SpringBoot项目?目录如何用IDEA2022创建并初始化一个SpringBoot项目?0. 环境说明1.  创建SpringBoot项目 2.编写初始化代码0. 环境说明IDEA2022.3.1JDK1.8SpringBoot1.  创建SpringBoot项目        打开IDEA,选择NewProject创建项目。        填写项目名称、项目构建方式、jdk版本,按需要修改项目文件路径等信息。        选择springboot版本以及需要的包,此处只选择了springweb。        此处需特别注意,若你使用的是jdk1

  9. ruby - 如何将 Interactive Ruby 整合到我的开发过程中? - 2

    我正在尝试找到一种更好的方法将IRB与我的常规ruby​​开发集成。目前我很少在我的代码中使用IRB。我只用它来验证语法或尝试一些小的东西。我知道我可以将我自己的代码加载到ruby​​中作为一个require'mycode'但这通常不符合我的编程风格。有时我要检查的变量超出范围或在循环内。有没有一种简单的方法可以启动我的脚本并在IRB内的某个点卡住?我想我正在寻找一种更简单的方法来调试我的ruby​​代码而不破坏我的F5(编译)键。也许有经验的ruby开发者可以和我分享一个更精简的开发方法。 最佳答案 安装ruby​​-debugg

  10. ruby - 使用 Drupal 和 Ruby。有没有人整合两者? - 2

    我开始了一个小型网络项目并使用Drupal来构建它。到目前为止,还不错:您可以快速建立一个不错的面向CMS的网站,通过模块添加社交功能,并且您有一个广泛的API可以在一个架构良好的平台中进行自定义。现在问题来了:网站的增长超出了最初的计划,我发现自己正处于认真开始为它编写代码的境地。由于Drupal项目,我对PHP有了新的认识,但我想用Ruby来做。我会感觉更舒服,以后维护起来更容易,我可以在其他Ruby/Rails应用程序中重用它。随着时间的推移,我想我会用Ruby重写Drupal中的现有部分。基于此,问题是:是否有人将两者(成功或失败的故事)结合起来?这是一个相当大的决定,但我在G

随机推荐