SpringCloudAlibaba服务熔断、限流——Sentinel

Sentinel

本专栏学习内容来自尚硅谷周阳老师的视频

有兴趣的小伙伴可以点击视频地址观看

简介

Sentinel是Alibaba公司推出的一个熔断与限流工具,相当于我们之前学习的Hystrix,可以解决服务使用中的各种问题,例如:服务雪崩、服务降级、服务熔断、服务限流。中文文档

image-20230424102911379

下载与安装

直接去github上下载即可,下载链接

小黄下载的是1.8.6的版本,直接下载jar包即可

image-20230424103037320

下载完之后,直接启动jar包即可,这里要注意Sentinel占用的是8080端口

image-20230424103128000

下载完成,可以通过localhost:8080访问可视化界面,默认用户名密码都是sentinel

image-20230424103219880

初始化演示工程

为了更方便的理解Sentinel以及后续的使用,我们先来玩一个小demo

接下来的微服务,我们都采用SpringCloud Alibaba那一套

启动Nacos

学习阶段,为了方便启动单机版的Nacos即可

startup.cmd -m standalone

创建工程

新建cloudalibaba-sentinel-service8401服务

添加依赖

<dependencies>
    <!--nacos依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--sentinel持久化,之后会用到-->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
    <!--sentinel依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <!--openfeign服务调用-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <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>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

编写配置文件

server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos服务地址
    sentinel:
      transport:
        dashboard: localhost:8080 # 配置Sentinel dashboard地址
        port: 8719 # 默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口

management:
  endpoints:
    web:
      exposure:
        include: '*' # 暴露所有端点

启动类

@EnableDiscoveryClient
@SpringBootApplication
public class MainApp8401 {
    public static void main(String[] args) {
        SpringApplication.run(MainApp8401.class, args);
    }
}

业务类

@RestController
public class FlowLimitController {
    @GetMapping("/testA")
    public String testA() {
        return "------testA";
    }

    @GetMapping("/testB")
    public String testB() {
        return "------testB";
    }
}

启动Sentinel

直接运行jar包即可

java -jar sentinel-dashboard-1.8.6.jar

测试

此时我们启动8401服务,发现sentinel控制台空空如也

image-20230424105443353

这是因为sentinel是懒加载机制,当你第一次访问接口之后,就会显示了,如下图所示

image-20230424105617668

流量控制

流量控制,简称流控,主要是对高并发请求数量多的接口进行流量管控,防止服务器垮掉。

感兴趣的同学可以看一下 官方文档

使用

比如我要对/testA接口进行流控,可以点击这个按钮,新增流控规则

image-20230424131815223

流量规则新增时有几个名词,我们需要先来提前了解一下

  • 资源名:唯一名称,默认请求路径
  • 针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default,不区分来源
  • 阈值类型/单机阈值:
    • QPS:每秒钟的请求数量,当调用该api的QPS达到阈值时,进行限流
    • 线程数:当调用该api的线程数达到阈值时,进行限流
  • 是否集群:不需要集群
  • 流控模式:
    • 直接:api达到限流条件时,直接限流
    • 关联:当关联的资源达到阈值时,就限流自己
    • 链路:只记录指定链路上的流量,指定资源从入口资源进来的流量,如果达到阈值,就进行限流
  • 流控效果:
    • 快速失败:直接失败,抛异常
    • Warm Up:根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值
    • 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效

流控模式

直接(默认)

系统默认是直接->快速失败两者搭配

配置说明

当我们对/testA进行如下配置时,表示1秒钟只能有一次请求,如果请求过快,直接抛异常

image-20230424132719828

测试

疯狂请求/testA会出现以下错误

image-20230424132847004

关联

配置说明

以下配置表示:当/testB一秒钟之内访问超过一次,那么就对/testA进行限流

举个例子:当一个接口调用支付微服务时,支付微服务需要调用第三方接口,假如支付微服务达到阈值了,我们可以直接限制最前面的接口

image-20230424132937265

测试

使用postman工具,对/testB接口进行调用,如下设置表示,每个0.8秒发送1一个请求,一共发送10个

image-20230424133611088

运行时,访问/testA会报错

image-20230424133649031

链路

与关联类似

流控效果

快速失败(默认)

这个已经演示过了,直接抛异常

是由com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController类进行处理的

Warm Up

配置说明

当我进行如下配置时表示,刚开始时,QPS为10/冷加载因子(3)就是3,也就是说刚开始访问/testA时,一秒钟最多允许访问3次,而在5秒后单机阈值提高,一秒钟最多允许访问10次

image-20230424134345743

是由com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController进行处理的,并且他默认冷加载因子为3

image-20230424134804887

排队等待

image-20230424140338218

配置说明

当我们对/testA进行如下设置表示:每隔200ms才允许通过下一个请求

image-20230424140406753

测试

通过postman并发10个请求

image-20230424140521192

每个请求至少都间隔了200ms

image-20230424140554537

熔断降级

概念

现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。

熔断策略

Sentinel 提供以下几种熔断策略:

  • 慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
  • 异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
  • 异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

降级策略实战

慢调用比例

配置说明

在1000毫秒,也就是1秒内,如果发送到/testC的请求数数量大于5,并且在这些请求中,所有请求的响应时长(因为比例与阈值为1,所以是所有的请求响应时长)都大于200毫秒,也就是都大于0.2秒的时候,进入熔断状态,熔断时长为2秒,若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。

image-20230424150842539

测试

模拟接口调用超时

    @GetMapping("/testC")
    public String testC() throws InterruptedException {
        Thread.sleep(1000);
        return "------testC";
    }

并发20个请求

image-20230424151219428

在五个请求后,服务被熔断降级

image-20230424151323273

异常比例

配置说明

在1000毫秒,也就是1秒内,如果发送到/testC的请求数数量大于5,并且在这些请求中,有50%的请求异常,则进入熔断状态

image-20230424151600108

测试

模拟接口调用超时

    @GetMapping("/testC")
    public String testC() throws InterruptedException {
        int i = 10 /0 ;
        return "------testC";
    }

image-20230424151709424

异常数

配置说明

在1000毫秒,也就是1秒内,如果发送到/testC的请求数数量大于5,并且在这些请求中,有2个请求异常,则进入熔断状态,异常数的熔断时长是分钟级别的,也就是说最小为1分钟!

image-20230424152730046

热点Key限流

概念

热点即经常访问的数据,很多时候我们希望统计或者限制某个热点数据中访问频次最高的TopN数据,并对其访问进行限流或者其它操作

实操

现在我们有这么一个接口,我希望在他带有参数p1时对其进行限流

@GetMapping("/testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                         @RequestParam(value = "p2",required = false) String p2){
    return "------testHotKey";
}

修改代码以及sentinel

我们需要借助到@SentinelResource注解

  • 资源名:与value值对应
  • 参数索引:0代表第一个参数,也就是p1

image-20230424170252848

测试

启动服务,对该接口请求,当请求带有p1时,达到阈值会限流,控制台以及页面都会报错

image-20230424170948004

自定义异常

和Hystrix类似,通过blockHandler属性来定义处理方法

兜底方法参数BlockException不可省略!

    @GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                             @RequestParam(value = "p2",required = false) String p2){
        return "------testHotKey";
    }

    public String deal_testHotKey(String p1, String p2, BlockException exception){
        return "------testHotKey error :" + exception;
    }

image-20230424171702437

参数例外项

除了上述对有无参数的限流之外,Sentinel还提供了对指定值的特殊处理,例如当p1='abc'时,阈值放大到200,打开高级选项进行如下设置

需要注意的是参数类型只支持基本类型以及String

image-20230424171854688

多提一句,热点Key限流只处理他自己的异常,程序中出现异常还是由程序本身进行处理,并不会走到兜底方法中

系统规则

概述

系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。

系统规则支持以下的模式:

  • Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5
  • CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

实操

在生产环境中慎用系统保护规则!

一旦达到阈值,整个服务都无法访问

我们玩一个简单一点的,入口QPS,当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

设置

对Sentinel进行如下设置,当一秒钟请求次数达到一次意思,就会触发系统保护,所有的接口都会禁止访问

image-20230424172604284

image-20230424172742783

@SentinelResource

概述

有如下接口,注册到Sentinel中,可以按照Url地址或者资源名对其进行限流

@RestController
public class RateLimitController {
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource", blockHandler = "handleException")
    public CommonResult byResource() {
        return new CommonResult(200, "按资源名称限流测试OK", new Payment(2023, "serial001"));
    }

    public CommonResult handleException(BlockException exception) {
        return new CommonResult(444, exception.getClass().getCanonicalName() + "\t 服务不可用");
    }
}

如下图所示/byResource是按照Url地址限流,对应着GetMappingbyResource是按照资源名限流,对应着value

image-20230425084659351

问题

通过@SentinelResource(value = "byResource", blockHandler = "handleException")blockHandler属性,可以设置服务的兜底解决方案,但还是会出现跟Hystix中一样的问题

  1. 依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观。
  2. 每个业务方法都添加一个兜底的,那代码膨胀加剧。
  3. 全局统一的处理方法没有体现。

解决方案

创建自定义处理器

处理方法必须是public static

public class CustomerBlockHandler {
    public static CommonResult handleException(BlockException exception){
        return new CommonResult(2023,"自定义的限流处理信息......CustomerBlockHandler");
    }
}

修改接口

  • blockHandlerClass:代表使用哪个类来处理
  • blockHandler:类中的哪个方法来处理
@GetMapping("/byResource")
@SentinelResource(value = "byResource",blockHandlerClass = CustomerBlockHandler.class,blockHandler = "handleException")
public CommonResult byResource() {
    return new CommonResult(200, "按资源名称限流测试OK", new Payment(2023, "serial001"));
}

服务熔断

前期准备

使用sentinel整合ribbon+openFeign+fallback实现服务熔断

准备两个服务提供者9003/9004,一个消费者84

提供者9003/9004

pom文件

<dependencies>
    <!--nacos依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--sentinel持久化,之后会用到-->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
    <!--sentinel依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <!--openfeign服务调用-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <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>
    <dependency>
        <groupId>com.yellowstar.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

配置文件

server:
  port: 9003

spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

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

业务类

@RestController
public class PaymentController {
    @Value("${server.port}")
    private String serverPort;

    public static HashMap<Integer,Payment> hashMap = new HashMap();

    static {
        hashMap.put(1, new Payment(1, "28a8c1e3bc2742d8848569891fb42181"));
        hashMap.put(2, new Payment(2, "bba8c1e3bc2742d8848569891ac32182"));
        hashMap.put(3, new Payment(3, "6ua8c1e3bc2742d8848569891xt92183"));
    }

    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult paymentSQL(@PathVariable("id") int id) {
        Payment payment = hashMap.get(id);
        CommonResult result = new CommonResult(200, "from mysql,serverPort:  " + serverPort, payment);
        return result;
    }
}
消费者84

pom文件

与提供者一致

配置文件

server:
  port: 84

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        #配置Sentinel dashboard地址
        dashboard: localhost:8080
        #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
        port: 8719

#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-payment-provider

RestTemplate配置

对RestTemplate配置负载均衡

@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

业务类

@RestController
@Slf4j
public class CircleBreakerController {
    public static final String SERVICE_URL = "http://nacos-payment-provider";

    @Resource
    private RestTemplate restTemplate;

    @RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback")
    public CommonResult fallback(@PathVariable int id) {
        CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

        if (id == 4) {
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
        } else if (result.getData() == null) {
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }

        return result;
    }
}

Ribbon系列

说明

@SentinelResource有两个属性

  • fallback:管运行异常
  • blockHandler:管Sentinel配置违规
没有任何配置

在没有任何配置的情况下,程序报错会直接返回error页面

image-20230425103933492

只配置fallback

修改84业务代码

@RequestMapping("/consumer/fallback/{id}")
@SentinelResource(value = "fallback" , fallback = "handlerFallback")
public CommonResult fallback(@PathVariable int id) {
    CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

    if (id == 4) {
        throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
    } else if (result.getData() == null) {
        throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
    }
    return result;
}

public CommonResult handlerFallback(@PathVariable  int id,Throwable e) {
    Payment payment = new Payment(id,"null");
    return new CommonResult(444,"兜底异常handlerFallback,exception内容  "+e.getMessage(),payment);
}

测试

当程序出现异常时,会交给兜底方法来处理

image-20230425104429547

只配置blockHandler

此配置需要综合Sentinel,和之前演示的效果一样

修改业务代码

    @RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback" , blockHandler = "blockHandler")
    public CommonResult fallback(@PathVariable int id) {
        CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

        if (id == 4) {
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
        } else if (result.getData() == null) {
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }
        return result;
    }

    public CommonResult blockHandler(@PathVariable  int id, BlockException blockException) {
        Payment payment = new Payment(id,"null");
        return new CommonResult(445,"blockHandler-sentinel限流,无此流水: blockException  "+blockException.getMessage(),payment);
    }
同时配置fallback和blockHandler

修改业务代码

    @RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback" , blockHandler = "blockHandler", fallback = "handlerFallback")
    public CommonResult fallback(@PathVariable int id) {
        CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

        if (id == 4) {
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
        } else if (result.getData() == null) {
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }
        return result;
    }

    public CommonResult blockHandler(@PathVariable  int id, BlockException blockException) {
        Payment payment = new Payment(id,"null");
        return new CommonResult(445,"blockHandler-sentinel限流,无此流水: blockException  "+blockException.getMessage(),payment);
    }

    public CommonResult handlerFallback(@PathVariable  int id,Throwable e) {
        Payment payment = new Payment(id,"null");
        return new CommonResult(444,"兜底异常handlerFallback,exception内容  "+e.getMessage(),payment);
    }

测试

通过测试可以发现blockHandler挡在fallback之前,一旦触发了blockHandler就不会进入程序执行

image-20230425104923851

忽略属性

通过以下属性配置,可以让Sentinel忽略指定错误,不交给fallback处理

@SentinelResource(value = "fallback" , blockHandler = "blockHandler", fallback = "handlerFallback"
        ,exceptionsToIgnore = {IllegalArgumentException.class})

Feign系列

激活Sentinel对Feign的支持

feign:
  sentinel:
    enabled: true # 激活Sentinel对Feign的支持

主启动类激活Feign

@EnableFeignClients

Feign远程调用业务接口

@FeignClient(value = "nacos-payment-provider", fallback = PaymentFallbackService.class)
public interface PaymentService {
    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult paymentSQL(@PathVariable("id") int id);
}

兜底方法处理类

@Component
public class PaymentFallbackService implements PaymentService {
    @Override
    public CommonResult paymentSQL(int id) {
        return new CommonResult(444, "服务降级返回,没有该流水信息", new Payment(id, "errorSerial......"));
    }
}

测试

此时关闭提供者服务,发现可以被兜底方法处理

image-20230425111547039

规则持久化

小黄在学习的过程中遇到了很烦的问题,当我们程序重启时,Sentinel定义的规则就会消失,在生产环境中我们肯定需要将配置规则持久化。

做法

将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上sentinel上的流控规则持续有效

实操

添加相关依赖

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

修改配置文件

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 
    sentinel:
      transport:
        dashboard: localhost:8080 
        port: 8719 
      datasource: ## 以下是新增
        ds1:
          nacos:
            server-addr: localhost:8848
            data-id: ${spring.application.name}
            group-id: DEFAULT_GROUP
            data-type: json
            rule-type: flow

nacos创建配置

json配置介绍

  • resource:资源名称;

  • limitApp:来源应用;

  • grade:阈值类型,0表示线程数,1表示QPS;

  • count:单机阈值;

  • strategy:流控模式,0表示直接,1表示关联,2表示链路;

  • controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;

  • clusterMode:是否集群。

image-20230425112609530

测试

当我们重启服务时Sentinel会读取Nacos中的相关配置

image-20230425112745967

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Alibaba 提供了多种服务限流的解决方案,其中比较常用的是通过使用 Sentinel 来实现服务限流Sentinel 是阿里巴巴开源的一款强大的流量控制组件,它提供了实时监控、熔断降级、系统保护等功能。下面简单介绍一下在 Spring Cloud Alibaba 中如何使用 Sentinel 进行服务限流。 首先,需要在项目的依赖中引入 Sentinel 相关的依赖,可以在 Maven 或者 Gradle 中添加如下配置: Maven: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> ``` Gradle: ``` implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel' ``` 接下来,在启动类上添加 `@EnableSentinel` 注解,开启 Sentinel 功能。 然后,在需要进行限流的方法上添加 `@SentinelResource` 注解,并指定相应的限流规则。例如: ```java @SentinelResource(value = "hello", blockHandler = "blockHandler") public String hello() { return "Hello World"; } public String blockHandler(BlockException ex) { return "Blocked by Sentinel"; } ``` 上述代码中,`@SentinelResource` 注解中的 value 属性是资源名称,blockHandler 属性指定了限流或者熔断降级时的处理方法。 最后,可以通过 Sentinel 控制台进行限流规则的配置和查看实时监控数据。控制台的地址为:http://localhost:8080。 以上就是在 Spring Cloud Alibaba 中使用 Sentinel 进行服务限流的简单介绍,希望对你有所帮助!如果还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值