SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流

一、简介

SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第1张图片
一句话解释就是阿里版本的Hystrix
能干什么:
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第2张图片
用于处理服务器使用中的各种问题:服务雪崩、服务降级、服务熔断、服务限流。

二、下载与安装

下载地址:
https://github.com/alibaba/Sentinel/releases
sentienl由2部分组成:
在这里插入图片描述
因此下载好的sentinel.jar可以直接运行,前提是java环境OK和8080端口不被占用。
在控制台执行:

java -jar sentinel-dashboard-1.7.0.jar 

然后访问:localhost:8080页面,用户名和密码都是sentinel
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第3张图片

三、初始化演示工程

Nacos与Sentinel简单联合工程
1、启动Nacos8848。
2、建Model让注册进Nacos并让Sentinel监控。
建model
改pom:

  
        
            com.ty.springCloud
            cloud-api-commons
            ${project.version}
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        
        
            com.alibaba.csp
            sentinel-datasource-nacos
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-sentinel
        
        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            cn.hutool
            hutool-all
            4.6.3
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

建yml:

server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        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);
    }} 

controller类:

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

3、启动sentinel8080和微服务8401。
4、由于sentinel采用懒加载,所以此时在sentinel页面无任何显示,需访问一次localhost:8401/testA或者localhost:8401/testB,才会显示在sentinel页面。
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第4张图片

四、流控规则

1、基本介绍

SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第5张图片
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第6张图片在这里插入图片描述

2、流控模式+流控效果演示

①、直接+快速失败:(QPS模式下)
OPS(每秒钟的请求数量):当调用该api的QPS达到阈值时,进行限流。
直接:调用api达到限流条件时,直接限流。
快速失败:直接失败,报异常。

演示案例:
每一秒访问接口localhost:8401/testA的并发量不能超过1,超过1直接限流报异常
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第7张图片
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第8张图片
当1s访问/testA超过一次时显示页面:
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第9张图片
也可不想显示此报错信息,自己定义一个兜底fallback方法。后续会讲。

QPS与线程数都设置为1时区别:
例如银行网点办理业务,只有一个银行业务人员时,QPS相当于1s只允许一个办理人员进银行办理,当在银行外面要办理业务的人1s超过1个时,直接限流。而线程数则表示允许办理人员都进银行,但是每次只能一个进行办理。
即QPS为1s只允许一个请求。线程数表示1s只允许一个线程。
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第10张图片

②、关联+快速失败
关联:当关联的资源达到阈值时,限流自己。应用场景如支付和下订单,当支付达到阈值时,就限流下订单模块。
比如/testA关联/testB,当/testB达到访问阈值时,就限流/testA。下图的单机阈值是针对/testB设置的。
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第11张图片
③、直接+Warm Up(预热):
Warm Up:跟进codeFactor(冷加载因子,默认3)的值,从阈值/codeFactor开始,经过预热时长,才达到设置的QPS阈值。
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第12张图片
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第13张图片

举例:
由于设置Warm Up模式,所以一开始的阈值为设定的10/3=3,预热时长为5s。所以会出现一开始1s中访问的请求大于3小于10时会出现限流情况,但过了预热时长后,请求大于3小于10就不会限流。
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第14张图片
常用应用场景: 秒杀系统在开启的瞬间会有很多的流量上来,很有可能把系统打死,预热方式就是为了保护系统,可慢慢的把流量放进来,慢慢的把阈值增长到设定的阈值。

④、直接+排队等候:
排队等候:匀速排队,让请求以匀速通过,阈值类似必须设置为QPS,否则无效。

匀速排队:
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第15张图片
阈值QPS=2,每隔500ms才允许通过下一个请求,是通过1s/2=500ms算出来的。

举例:
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第16张图片
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第17张图片
此时多个请求同时访问/testA时,控制台应该是没隔1s打印一次当前线程名称。可以用postman来实验。

五、降级规则

在这里插入图片描述
sentinel断路器没有半开状态。

1、RT

SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第18张图片
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第19张图片
举例:
若有一接口:

    @GetMapping("/testD")    
    public String testD(){        
        try { TimeUnit.SECONDS.sleep(1); 
        } catch (InterruptedException e) { 
            e.printStackTrace(); 
        }        
        log.info("testD 测试RT");       
        return "------testD";    }

执行该段程序需1s,即设定此程序的平均响应时间为1s。
设置RT,让其阈值为0.2s,时间窗口为2s。
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第20张图片
然后使用Jmeter,以每秒钟10个请求方式打过去。
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第21张图片
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第22张图片
此时访问TestD就会报错
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第23张图片
停止Jmeter后过2s在访问就正常
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第24张图片
是因为我们程序设计执行TestD方法睡眠1s也就是平均响应时间至少1s,加上每秒钟的请求为10次。
同时满足 1秒持续进入5个请求和平均响应时间>阈值这2个条件,所以会报错。

2、异常比例

在这里插入图片描述
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第25张图片
异常比列的降级条件为:
每秒钟的请求数QPS>5;
每秒的异常比例超过设定阈值;

举例:
异常比例设置为20%,以每秒10次请求访问一个除0方法接口。
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第26张图片

/testE中实现一个除0异常

    @GetMapping("/testE")
    public String testE(){
        int a = 10/0;
        return "------testE";
    }

若单次访问/testE,不走异常比例降级流程,即出现Error页面:
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第27张图片
若通过Jmeter模拟一秒中10次请求的方式同时访问/testE,则会出现降级报错页面:
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第28张图片

3、异常数

在这里插入图片描述
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第29张图片
一分钟内访问的请求出现异常的次数超过设定的阈值时,就降级并提示。而且时间窗口设定必须大于1分钟。
由于是出现异常的次数达到阈值才会出现降级提示页面,如全采用除0异常作请求,设定阈值为5,则前5次请求得到的都是除0错误页面,第6次才会出现降级提示页面。

六、热点key限流规则

SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第30张图片

1、针对具体参数的热点限流、限流时提示内容个性化配置

新建需测试的热点参数接口以及接口对应的限流时提示内容个性化配置:

    @GetMapping("/testHostKey")
    @SentinelResource(value = "testHostKey",blockHandler = "deal_HostKey")//value参数值需唯一,一般规范为rest地址去掉斜线,blockHandler为接口对应的限流时提示内容个性化配置
    public String testHostKey(@RequestParam(value = "a1",required = false)String a1,
                              @RequestParam(value = "a2",required = false)String a2){
        return "------testHostkey";
    }

    public String deal_HostKey(String a1, String a2, BlockException bl){ //deal_HostKey中参数需与引用的接口参数一致,且需BlockException
        return "------deal_HostKey,(′д` )…彡…彡";
    }

@HystrixCommand类似@SentinelResource
接口对应的限流时提示内容个性化配置的配置由@SentinelResource中的blockHandler参数值来配置。

sentinel中配置热点key限流:
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第31张图片
测试结果:1s请求超过1次时
在这里插入图片描述

2、参数例外项

当限流的参数是某个特殊值时,它的限流阈值和平时不一样。
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第32张图片
/testHoskKey中第一个参数的值为5时,它的阈值为200而不是1。
需要注意SentinelResource处理的是配置异常,而不是运行时异常
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第33张图片
使用上述兜底方案会出现的问题:
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第34张图片
在第八点中将解决它们。

七、系统规则

SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第35张图片

SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第36张图片

八、@SentinelResource

1、客户自定义限流处理逻辑

创建一个类用于用户自定义限流处理逻辑:

public class CustomerBlockHandler {

    public static String blockHandler_01(BlockException bl){
        return "------------global handler,blockHandler_01";
    }

    public static String blockHandler_02(BlockException bl){
        return "------------global handler,blockHandler_02";
    }
}

需注意定义的全局兜底方法需用static关键字修饰
然后兜底的业务走这个全局兜底配置类:

    @GetMapping("/testHandler")
    @SentinelResource(value = "testHandler",
            blockHandlerClass = CustomerBlockHandler.class,
            blockHandler = "blockHandler_02")      //指定以全局兜底类中的BlockHandler_02方法来兜底
    public String testHandler(){
        return "--------testHanlder";
    }
2、blockHandler和fallback

fallback走程序运行时异常需处理的兜底方法
blockHandler走sentinel配置时服务异常的兜底方法
fallback的配置方法同blockHandler类似
当两者都配置时:
在这里插入图片描述
也就说未达到设定阈值时走程序运行异常兜底,达到阈值后走sentinel配置兜底。

九、主要熔断框架比较

SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第37张图片
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第38张图片

十、规则持久化

1、是什么

一旦我们重启应用,Sentinel规则将消失,生产环境需要将配置规则进行持久化

2、如何持久化:

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

        
            com.alibaba.csp
            sentinel-datasource-nacos
        

yml文件中添加:

spring:
	cloud:
		sentinel:
			datasource:
		        ds1:
		          nacos:
		            server-addr:  localhost:8848
		            dataId: cloudalibaba-sentinel-service  #微服务名称
		            groupId: DEFAULT_GROUP
		            data-type: json
		            rule-type: flow

在nacos中新增配置规则json文件:
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第39张图片
data id和groupid要和yml文件中对应。
json文件内容:

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

SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第40张图片
配置完成后,只需访问一次testA,sentinel中出自动出现针对testA的流控规则。
SpringCloud第十三天之SpringCloud Alibaba Sentinel实现熔断与限流_第41张图片

你可能感兴趣的:(SpringCloud)