23springcloudAlibaba Sentinel

官网参考地址:https://github.com/alibaba/Sentinel/wiki
是什么:
  Spring Cloud Alibaba Sentinel 是面向于云原生微服务的高可用流控防护组件,
      主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性。 
      一句话解释,就是之前学习过的 Hystrix 升级版。

Hystrix VS Sentinel:

Hystrix
Sentinel
需要程序员手工搭建监控平台
单独一个组件、可以独立出来
没有一套Web界面可以给程序员进行更加细粒度化得配置,比如流控、速率控制、服务熔断、服务降级
直接界面化的细粒度统一配置

服务中遇到的各种问题:
    1.服务雪崩
    2.服务降级
    3.服务熔断
    4.服务限流

Sentinel分为两部分:
    1.核心库(java客户端):不依赖任何框架/库,能够运行与所有的java运行时环境,同样对Dubbo/Spring Cloud框架也有较好的支持
    2.控制台(Dashbord):基于springboot开发,打包后可以直接运行,不需要额外的tomcat等应用容器。
    
sentinel的dashbord安装(前台页面)
    下载地址:https://github.com/alibaba/Sentinel/release

如下图所示:
    下载的前台页面包是springboot写的jar包,所以启动方式是java -jar 的形式启动,需要注意的是,该端口为8080,所以要保障8080端口无人占用!!
启动成功后登陆:http://localhost:8080/
用户名/密码:sentinel/sentinel

2.编写java客户端代码:
    1.pom文件中的写法:没有用到alibaba的服务配置中心nacos-config,所以未引入该包:spring-cloud-starter-alibaba-nacos-config
        <dependencies>
            重点1
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            </dependency>
            重点2:
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-datasource-nacos</artifactId>
            </dependency>
            重点3:
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
            ...
        </dependencies>
    2.application.yml中的配置:
        server:
              port: 8401
            spring:
              application:
                name: cloudalibaba-sentinel-service
              cloud:
                nacos:
                  discovery:
                    #Nacos服务注册中心地址
                    server-addr: 192.168.2.129:8848
                sentinel:
                  transport:
                    #配置sentinel的dashbord地址
                    dashboard: localhost:8080
                    #默认是8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
                    #固定写法
                    port: 8719
            management:
              endpoints:
                web:
                  exposure:
                    include: '*'
        
        3.启动类写法:
            @SpringBootApplication
            重点:@EnableDiscoveryClient标签,使注册中心可以扫描到
            @EnableDiscoveryClient
            public class ConfigClientApplication3377 {
                public static void main(String[] args) {
                        SpringApplication.run(ConfigClientApplication3377.class, args);
                    }
            }
        4.控制层代码:简单的请求方法
            @RestController
            @Slf4j
            public class SentinelController {
                @GetMapping("/sentinel/id/{id}")
                public int getIn(@PathVariable("id") int id){
                    log.info("调用获取id方法:"+id);
                    return id;
                }
            
                @GetMapping("/sentinel/date/{date}")
                public String getDate(@PathVariable("date") String date){
                    log.info("调用日期请求方法!"+date);
                    return DateUtil.now();
                }
            }

1.sentinel页面:

2.Nacos页面(服务注册中心)

1.流控讲解:

1.资源名:唯一的名称,默认请求路径
2.针对来源:Sentinel可以针对调用者进行限流,填写微服务名称,默认是default(不区分来源)
3.阈值类型/单机阈值:
    3.1 QPS(每秒钟的请求数量):当调用该api的QPS达到阈值的时候,进行限流
    3.2 线程数:当调用该api的线程数达到阈值的时候,进行限流。

4.是否集群:不需要集群
5.流控模式:
    5.1 直接:API达到限流条件时,直接限流
   5.2 关联:当关联的资源达到阈值时,就限流自己
   5.3 链路: 只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流。)【api级别的针对来源】

6.流控效果:
    1.快速失败:直接失败,抛异常
    2.Warm Up:根据codeFactor(冷加载因子,默认是3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值
    3.排队等待:匀速排队,让请求以均匀的速度通过,预支类型必须设置为qps,否则无效

1.流控规则

1.1 流控模式:直接

1.QPS:每秒钟的请求次数
2.并发线程数:内部设置同时的并发量

1.2 流控模式:关联

 

流控模式选择关联:如下
总结:
    如果访问/sentinel/id/1时,发现其关联资源无法访问,会导致其/sentinel/id/1的访问失败,返回官方信息:Blocked by Sentinel (flow limiting)

1.3 流控模式:链路

2.流控效果:预热

QPS的单机阈值是10:即每秒最大支持10次的访问
当流控效果为:warm up(预热)
冷启动的默认coldFactor为3,即请求QPS从:单机阈值/冷启动因子(coldFactor默认是3),经过预热时长逐渐升值设定的QPS阈值

场景:平时的访问量很低,突然访问量剧增,容易把系统压垮,有了预热,使系统逐渐增加访问量,有个过程
常见用到秒杀系统里

2.流控效果:排队等待

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

 

降级规则

RT(平均响应时间,秒级)
    平均响应时间,超出阈值 且 在时间窗口通过的请求>=5,两个条件同时满足后触发降级
    窗口期过后关闭断路器。
    RT最大4900(更大的要通过-Dcsp.sentnel.staticstic.max.rt=xxxx才能生效)
    
异常比例:
    QPS >=5 且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级
    
异常数:
    异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级。
    
Sentinel我们断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制。
让请求快速失败,避免影响到其他的资源而导致级联错误

当资源被降级后,在接下来的降级时间窗口之内,对该资调用都自动熔断(默认是抛出DegrareException)
Sentinel的断路器没有半开状态(半开状态参考Hystrix)

热点key限流

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:
商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
 

具体的测试代码结构如下:重要的是@SentinelResource标签的使用:
    控制层代码:
        @GetMapping("/sentinel/testHotkey")
        重点1:@SentinelResource标签的石永红,value值是在sentinel页面上配置的资源名称,blockHandler 定义的就是兜底的方法
        @SentinelResource(value = "testHotkey",blockHandler = "deal_testHotkey")
        public String testHotkey(
                @RequestParam(value = "parm1",required = false) String parm1,
                @RequestParam(value = "parm2",required = false) String parm2
        ){
            log.info("测试热点限流:第一个参数->"+parm1+" 第二个参数:"+parm2);
            return "测试热点限流:第一个参数->"+parm1+" 第二个参数:"+parm2;
        }
        public String deal_testHotkey(){
            return "测试热点数据的兜底方法!";
        }

系统规则

做整体的配置

@SentinelResource标签

1.场景一:如何设置共有的降级处理方法(即降级处理方法和原业务逻辑分开)
   当访问 /testGlobl点击量超过1秒1次后,会调用到公共的降级方法进行服务降级!

   
      @SentinelResource(value = "testGloble",
        blockHandlerClass = MyHandler.class,
        blockHandler = "hadleException1")   
属性解析:
     1.value :对应的资源名称,和sentinel上配置的一样
    2.blockHandlerClass:公共的降级类
    3.blockHandler :对应的降级方法

服务熔断

 @SentinelResource(value = "testGloble",
        blockHandlerClass = MyHandler.class,
        blockHandler = "hadleException1")   
上述的配置只能解决sentinel页面上配置的限流导致的降级服务降级问题,如果是程序运行时异常,应该如何进行服务熔断和降级呢
使用fallback指定运行时异常导致的服务熔断和降级方法
样例:
    @GetMapping("/testGloble")
    @SentinelResource(value = "testGloble",
            blockHandlerClass = MyHandler.class,
            blockHandler = "hadleException1",
            重点:使用fallback指定程序运行时异常导致的服务熔断和降级方法!
            fallback = "deal_fall")
    public String testGloble(){
        //重点2:这里会抛出java运行时异常,当访问时可以走到下面的运行时异常服务熔断降级方法
        int a=10/0;
        return DateUtil.now();
    }
    public String deal_fall(){
        return "运行时异常导致的熔断降级!";
    }
    


总结:
    1.SentinelResource中的blockHandlerClass/blockHandler 只能处理sentinel页面上配置的限流等导致的服务熔断和限流(sentinel控制台的配置违规),
        不处理java运行时异常导致的问题(页面会直接报错,但当又满足了sentinel控制台的控制违规,是会走其服务降级方法)
    2.fallback:可以解决java运行时异常的服务熔断和降级
    3.两者的配合使用:
        3.1 当出现java运行时异常时,会走fallback的服务熔断降级方法
        3.2 但当又有java运行时异常,又满足sentinel控制台配置的blockHandler配置,以sentinel即blockHandler的为主!走其服务熔断降级方法!

 

posted @ 2022-05-29 18:04  努力的达子  阅读(32)  评论(0编辑  收藏  举报