springcloud alibaba sentinel熔断降级

简介

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护 等多个维度保护服务的稳定性。

sentinel相当于hystrix的升级版,加入了web界面,能够实时在线的改变流量策略。

Sentinel 分为两个部分:

  • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
  • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

安装

官方下载架包后运行命令:

java -Dserver.port=8858 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

访问localhost:8858 即可进入控制台界面,账户密码都为sentinel

sentinel控制台使用

https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel

按照文档配置后,访问localhost:8080可以看到如下画面。如果没有左边的服务名,可以尝试注销账号重新登陆。

流控规则

流控模式:

  • 直接:API达到限流条件时,直接限流。
  • 关联:当关联的资源达到阈值时,就限流自己。
  • 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【API级别的针对来源】。

流控效果:

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

熔断(降级)规则

RT(平均响应时间,秒级):

  • 平均响应时间 超出阈值 且 在时间窗口内通过的请求>=5,两个条件同时满足后触发降级。
  • 窗口期过后关闭断路器。
  • RT最大4900(更大的需要通过-Dcsp.sentinel.statistic.max.rt=XXXX才能生效)。

异常比列(秒级)

  • QPS >= 5且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级 。

异常数(分钟级)

  • 异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级。

热点key

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制

用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

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

下面的代码中参数p1,p2就是热点。deal_testHotKey为被sentinel限流后的兜底方法。

java 复制代码
@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 e){
        return "deal_testHotKey 兜底方法";
    }

下面设置会统计/testHotKey携带参数0(p1)的次数,如果在统计窗口(1s)内有超过单机阈值(1条)带有参数p1的请求,则会限流。

注意:这里的blockHandler对应的兜底方法只能在sentinel限流的时候才会触发,程序异常并不会走兜底方法。

参数例外项

  • 普通 - 超过1秒钟一个后,达到阈值1后马上被限流
  • 我们期望p1参数当它是某个特殊值时,它的限流值和平时不一样
  • 特例 - 假如当p1的值等于5时,它的阈值可以达到200

注意:参数的值应该是基本类型or String

系统规则(了解)

系统保护规则是从应用级别的入口流量进行控制,从单台机器的 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 达到阈值即触发系统保护。

@SentinelResource兜底方法配置

可以另外创建一个类来进行兜底方法的配置:

java 复制代码
public class CustomerBlockHandler {
    public static CommonResult handlerException(BlockException exception){
        return new CommonResult(4444,"用户自定义全局Exception: ",new Payment(2020L,"serial003"));
    }
    public static CommonResult handlerException2(BlockException exception){
        return new CommonResult(4444,"用户自定义全局Exception: ",new Payment(2020L,"serial003-2"));
    }
}

controller:通过blockHandlerClass指定类名,blockHandler指定选定的兜底方法。

java 复制代码
   @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandlerClass = CustomerBlockHandler.class,blockHandler = "handlerException")
    public CommonResult byResource(){
        return new CommonResult(200,"按资源名称访问限流测试OK",new Payment(2020L,"serial001"));
    }

整合nacos进行持久化存储

默认情况下,当我们在Sentinel控制台中配置规则时,控制台推送规则方式是通过API将规则推送至客户端并直接更新到内存中。一旦我们重启应用,规则将消失。

配置

引入依赖

java 复制代码
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

修改application.yml:

java 复制代码
spring:
  cloud:
    sentinel:
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-sentinel
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

在nacos中添加配置:

java 复制代码
[
    {
        "resource": "/rateLimit/byUrl",
        "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表示Warm Up,2表示排队等待;

clusterMode:是否集群。

之后可以发现Sentinel控制台已经有了如下限流规则:

相关推荐
荆州克莱4 分钟前
mysql中局部变量_MySQL中变量的总结
spring boot·spring·spring cloud·css3·技术
zquwei17 分钟前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
火烧屁屁啦1 小时前
【JavaEE进阶】初始Spring Web MVC
java·spring·java-ee
岁岁岁平安1 小时前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
北辰浮光1 小时前
[spring]XML配置文件标签
xml·spring
ZSYP-S2 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
qxlxi2 小时前
【Spring事务】深入浅出Spring事务从原理到源码
spring
路在脚下@3 小时前
Spring Boot @Conditional注解
java·spring boot·spring
小蜗牛慢慢爬行7 小时前
使用 AOP 在 Spring Boot 中实现跟踪和日志记录
java·开发语言·spring boot·后端·spring·日志记录
奕_奕7 小时前
SpringMVC
spring