700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > sentinel实现限流 降级 熔断配置和测试使用

sentinel实现限流 降级 熔断配置和测试使用

时间:2020-06-30 23:28:33

相关推荐

sentinel实现限流 降级 熔断配置和测试使用

sentinel实现限流、降级、熔断配置和测试使用

这篇是转载自:/qq_38322527/article/details/106253143

我仔仔细细的看了两遍,简直良心好文

一、Sentinel简介

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

《Sentinel github开源代码和文档介绍》

[问:]Sentinel 与 Hystrix 存在哪些不同?

Hystrix需要引入大量的pom依赖,以及需要在配置文件中做一定量的配置编写;其次使用流量监控等操作时,需要额外配置很多,过于麻烦。

Sentinel只需要引入对应pom依赖即可,能够在界面上直接进行配置,无需写太多的配置文件。

二、Sentinel 下载、安装和使用

2.1、下载sentinel

下载链接

启动、使用

使用 Sentinel 时,需要注意几点

端口占用为 8080 (与tomcat类似)

这是一个jar项目,使用 java -jar xxxxx.jar 启动

查看配置文件,并无端口号相关的配置信息,采取的是Springboot 默认的 8080端口启动。

[注意:]Sentinel需要额外注意端口信息

尝试采取指定端口号启动方式,但无效;可能是官方出现的隐藏bug。

后期如做配置,需要额外注意Sentinel 的端口信息

2.2、启动 Nacos、Sentinel

java -jar sentinel-dashboard-1.7.2.jar

访问:

localhost:8080

账号、密码分别为:sentinel

2.3、创建测试项目

创建子项目cloudalibaba-Sentinel-Server-8500

引入依赖信息:

<!-- SpringCloud ailibaba nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</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><!-- 使用 openfeign 组件 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- 使用 Sentinel 组件 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!-- sentinel 的数据持久化 --><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency>

编写配置文件信息,指明当前微服务的端口、服务别名以及让Sentinel监听当前微服务。

## 该服务的端口信息server:port: 8500## 服务别名和nacos服务注册发现地址配置spring:application:name: cloudalibaba-sentiner-servercloud:nacos:discovery:server-addr: localhost:8848sentinel: ## 流控transport:# sentinel dashboard的地址(sentinel的地址--8080监控当前8500微服务)dashboard: localhost:8080# 为应用开启额外的端口,上报监控信息# 默认为8719端口,加入被占用将会自动从8719开始+1扫描,直至找到未被占用的端口地址port: 8719## 监控相关management.endpoints.web.exposure.include: '*'

编写启动类和测试类:

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication@EnableDiscoveryClientpublic class SentinelApplication8500 {public static void main(String[] args) {SpringApplication.run(SentinelApplication8500.class,args);}}

import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class TestController {@RequestMapping("/test1")public String test1(){return "----this is test1";}@RequestMapping("/test2")public String test2(){return "----this is test2";}}

2.4、启动测试项目

启动测试项目cloudalibaba-Sentinel-Server-8500

在nacose中完成了服务的注册:

查看Sentinel,但是并无监控信息。

Sentinel是一款懒加载式的架构,需要对接口进行请求后,才能获得相关监控信息。

请求接口后再次刷新Sentinel并查看信息统计:

http://localhost:8500/test2

http://localhost:8500/test1

三、Sentinel 阈值类型和流控模式

界面配置专业词汇概述:

3.1、阈值类型 QPS、流控模式 直接

修改 /test1 请求的流控规则,如下图所示:

默认的高级设置为:

每秒允许请求数为1

请求并进行测试:

测试需要讲究快速点击缓慢点击

缓慢点击

快速点击

表示1秒内,查询1次请求OK;

如果请求在1秒内的次数高于1次,则进入快速失败流程,报默认的错误提示!

3.2、阈值类型 线程数、流控模式 直接

修改/test1的请求限流配置,将QPS更改为线程数

再次请求:

http://localhost:8500/test1

发现:

无论请求速率多么快,都不会进入限流回执

[问:]这是为什么?

分析问题前,需要了解QPS线程数这两种方式的区别:

修改处理接口:

import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class TestController {@RequestMapping("/test1")public String test1(){return "----this is test1";}@RequestMapping("/test2")public String test2(){return "----this is test2";}/*** 模拟 阈值类型 为 线程数* @return*/@RequestMapping("/test3")public String test3(){// 每次请求过来,都延时800毫秒做处理try {Thread.sleep(800);} catch (InterruptedException e) {e.printStackTrace();}return "----this is test3";}}

再次请求测试:

http://localhost:8500/test3

快速点击!

3.3、阈值类型 QPS、流控模式 关联

此次的配置采取如下方式:

当关联的资源达到限流条件时,开启限流

配置请求 /test2 限流QPS,关联 /test1

文档解释现象:

/test1 与 /test2 有关联关系。

若 /test2 达到阈值时,会对 /test1 进行限流

实用背景:

下单和支付接口进行关联。

如若支付接口达到阈值,就限定下单接口少产生支付接口,缓解压力!

如何进行测试呢?

1、正常请求/test1,无关乎快速还是缓慢,都会是正常返回信息。

2、循环不断请求/test2,触发该接口的限流操作。

3、再次请求/test1,查看请求回执状态信息。

正常请求/test1

http://localhost:8500/test1

无论快慢,都是返回下列信息!

使用postman、jmeter等工具,迭代请求/test2,触发限流后,再次请求/test1查看回执状态信息:

运行 postman,浏览器访问:http://localhost:8500/test1

现象:

/test2触发了限流,此时的/test1请求将会受到影响!

/test2限流结束,/test1才能继续请求得到回执!

3.4、QPS、链路

链路:当从某个接口过来的资源达到限流条件时,开启限流。

链路流控是针对上级接口

[注意:]此处有巨坑!

1、Sentinel 从1.6.3版本开始,Sentinel Web Filter 默认收敛所有URL的入口Context,因此链路限流不生效。

2、1.7.0版本开始,官方在CommomFilter中引入了一个WEB_CONTEXT_UNIFY参数,用于控制是否收敛context。默认为true(默认收敛所有),配置为false则可根据不同URL进行链路的限流操作。

3、Spring Cloud Alibaba 在2.1.1.RELEASE版本后,可以根据配置spring.cloud.sentinel.filter.enabled: false来关闭自动收敛。

如何进行测试呢?

1、修改父pom中的Spring Cloud Alibaba 的依赖版本信息

<!-- 将2.1.0版本更改为2.1.1版本 --><spring.cloud.alibaba.version>2.1.1.RELEASE</spring.cloud.alibaba.version>

2、增加一个服务接口,使得两个controller均可调用。

import com.alibaba.csp.sentinel.annotation.SentinelResource;import org.springframework.stereotype.Service;@Servicepublic class ServiceImpl {//必须加上 @SentinelResource 注解,此处该注解类似 @HystrixCommand@SentinelResource("message")public String message(){return "message";}}

3、编写配置类文件,设置WEB_CONTEXT_UNIFYfalse

import com.alibaba.csp.sentinel.monFilter;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class FilterContextConfig {@Beanpublic FilterRegistrationBean sentinelFilterRegistration(){FilterRegistrationBean registrationBean = new FilterRegistrationBean();registrationBean.setFilter(new CommonFilter());registrationBean.addUrlPatterns("/*");//入口资源关闭聚合registrationBean.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY,"false");registrationBean.setName("sentinelFilter");registrationBean.setOrder(1);return registrationBean;}}

4、在yml配置文件中,需要新增配置信息

5、编写请求控制器类,调用服务中的方法。

import cn.linkpower.servive.ServiceImpl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class TestController {/***链路demo*/@Autowiredprivate ServiceImpl serviceImpl;@RequestMapping("/message1")private String message1(){serviceImpl.message();return "lianlu message1";}@RequestMapping("/message2")private String message2(){serviceImpl.message();return "lianlu message2";}}

6、启动并测试

先分别请求 http://localhost:8500/message1 和 http://localhost:8500/message2 使得Sentinel中存在监控信息。

设置Sentinel中的 message信息。采取链路形式构成关联

再次快速请求 http://localhost:8500/message1 和 http://localhost:8500/message2

[总结:]

当配置message资源 链路 /message1 请求接口时,如果 /message1 出现请求超过限流值,则会触发限流,但 /message2 并不受影响!

反之,/message2 受影响,但 /message1不受影响!

[注:]@SentinelResource 注解在博客下会说明!

四、Sentinel 流控效果

此处的效果测试,均采用阈值类型:QPS流控模式:直接

4.1、直接

直接失败,抛出异常,不做任何额外处理,是最简单的方式。

4.2、Warm Up

从开始阈值,到最大QPS阈值会有一个缓冲阶段,

一开始的阈值是最大QPS阈值的1/3,然后缓慢增长,直到最大阈值,适用于突然增大的流量转化为缓步增长。

避免突然大流量造成服务器的宕机!

阈值最初为10;

最初的处理请求数最大为:10/3=3;

在5s时间内,由3缓慢升为10。

使用jmeter进行压测

创建线程组:

创建请求:

突然出现大量请求,不会直接进行实际处理,会将请求预热后在做处理

4.3、排队等待

让请求以均匀的速率通过,单机阈值为每秒通过的请求数,其余的排队等待;

其次,还可以设置一个排队等待的超时时间,若请求在超时时间内还未被处理,则会被丢弃。

达到的目的:

匀速处理多个请求,而不是一开始超过阈值的请求直接失败!

编写测试接口:

/*** 队列等待模式测试*/@RequestMapping("/test4")public String test4(){log.info("当前线程执行信息:{}",Thread.currentThread().getName());return "duilie wait test4";}

设置 Jmeter 一个线程每秒钟访问俩次:

打印日志信息:

观察发现:

每秒钟限定处理一个请求数。

但是jmeter每秒钟发送2个请求。

设置了延迟等待 500ms后,只有少数请求会进入降级!

五、Sentinel熔断降级

平均响应时间 (DEGRADE_GRADE_RT):当 1s 内持续进入 N 个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位),那么在接下的时间窗口(DegradeRule 中的timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。注意Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx来配置。异常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):当资源的每秒请求量 >= N(可配置),并且每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。异常数 (DEGRADE_GRADE_EXCEPTION_COUNT):当资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。

5.1、RT 平均响应时间

1、如果请求的平均响应数超过阈值(ms),则会进入准降级状态

2、如果接下来1s内持续进入5个请求,他们的RT持续超过了这个阈值,那么在接下来的时间窗口(s)内,就会对这个服务进行降级

3、RT默认最大为4900ms,如果需要更大,可以通过 -Dcsp.sentinel.statistic.max.rt=xxx 进行配置。

配置案例:

java代码逻辑为:

/*** 降级测试* @param name* @return*/@RequestMapping("/jiangji")public String jiangji(@RequestParam("name") String name){//当请求参数为 1 时,响应延迟600ms 也就是RT可以配置允许时间比这个数低的值if("1".equalsIgnoreCase(name)){try {Thread.sleep(600);} catch (InterruptedException e) {e.printStackTrace();}}log.info("请求的name:{},时间为:{}",String.valueOf(name),new Date().getTime());return "jiangji test name="+String.valueOf(name)+" 当前时间:"+new Date().getTime();}

先进行请求,然后sentinel中配置图如下:

请求测试:

1、正常请求:

http://localhost:8500/jiangji?name=2

不会出现熔断保护。

2、异常请求:

http://localhost:8500/jiangji?name=1

熔断保护时间内,请求正常流程:

http://localhost:8500/jiangji?name=11

保护时间过后,在请求正常流程:

http://localhost:8500/jiangji?name=11

[总结]

1、配置熔断保护的接口,如果不出现超时情况时,不会触发熔断保护降级。

2、当设定RT为500ms后,请求异常流程,1s内平均请求响应都超时并达到对应的数目(测试显示5个),会触发熔断保护,并保护10s(这个时间是时间窗口的配置)。

3、熔断保护期间内,正常请求也会被熔断、降级。

4、10s后,熔断结束,会重新对请求响应时间进行统计判断。

5.2、异常比例数

每秒的异常总数,占通过量的比值超过配置的值之后,触发熔断降级。

时间窗口和之前一样,属于熔断保护时间。

占的比值数范围为:[0.0,1.0];

代码案例:

/*** 异常触发熔断降级测试*/int a = 0;@RequestMapping("/exct")public String exct(){a ++ ;if(a % 3 == 0){//模拟异常throw new RuntimeException("请求取余数为0了");}return "异常导致的熔断降级测试";}

暂时未配置时,当请求数每次达到a % 3 == 0时,就会产生异常:

http://localhost:8500/exct

配置Sentinel,使得其具备熔断降级的策略:

由于a % 3 == 0触发异常,也就是说异常比例为1/3。只需要配置的数小于1/3即可。

请求测试:

http://localhost:8500/exct

正常缓慢请求时,依然和之前一致,出现报错信息。

当请求异常比例大于等于配置数时,出现熔断降级。

5.3、异常数

资源1分钟内的异常总数超过限定的阈值,触发熔断降级!

设定异常数为3,表示一分钟请求的异常出现了3个及以上,触发熔断降级!

[注意]此处有坑!

由于异常数是按照分钟统计的个数,时间窗口中的设置也必须要大于60s

不然会出现:结束熔断保护后仍可能继续熔断保护(不会释放!)

请求测试:

http://localhost:8500/exct

当请求出现异常的次数达到设定的值时,立马出现熔断降级现象。

当熔断保护的时间过了之后,释放,再次请求会重新进行统计!

六、Sentinel热点规则

热点参数流控规则。

何为热点:

热点即经常访问的数据。

热点限流的思想是什么?

假设某一时间段内的某个用户频繁的去访问,就可以采取热点规则方式,对其进行限流操作。

6.1、初级配置和测试

案例测试:

/*** 热点规则测试项* @param p1* @param p2* @return*/@RequestMapping("/hostkey")//名称唯一 但 热点规则 必须需要此项配置,无此注解不生效@SentinelResource(value = "hostkey",blockHandler = "fallback_hostkey")public String testHotKey(@RequestParam(value="p1",required = false) String p1,@RequestParam(value="p2",required = false) String p2){return "---- test Hot Key ----";}// 修改sentinel 降级的默认回执方法(传递参数的一致性,并且需要携带 BlockException)public String fallback_hostkey(String p1, String p2, BlockException blockException){return "限流咯。。。。";}

当不配置任何规则时,此时的回执信息为:

http://localhost:8500/hostkey

配置Sentinel中的热点规则属性。

当请求地址携带p1参数,且每秒钟的请求数高于配置的1次时,触发降级。

请求测试:

1、不携带参数,快速点击

http://localhost:8500/hostkey

2、携带参数,但不携带p1,快速点击

http://localhost:8500/hostkey?p2=33333

3、携带p1参数,缓慢点击

http://localhost:8500/hostkey?p1=33333

4、携带p1参数,快速点击

6.2、高级配置

针对个别用户频繁访问时,采取了限流操作(按照参数接受类型,但不是具体的数值)。

但是,针对管理员频繁的访问查看或测试数据时,此时不应限流。

配置项:

达到的目的,当p1为520时,限流量放大!

请求测试:

1、缓慢请求,p1非特定值

http://localhost:8500/hostkey?p1=52

2、快速请求,p1非特定值

3、缓慢请求,p1为特定值

http://localhost:8500/hostkey?p1=520

4、快速请求,p1为特定值(每秒请求大于2触发)

6.3、@SentinelResource 修饰的controller出现异常了会走blockHandler提示返回么?

修改controller,如下所示:

// 修改sentinel 降级的默认回执方法public String fallback_hostkey(String p1, String p2, BlockException blockException){return "限流咯。。。。";}/*** 热点规则测试项* @param p1* @param p2* @return*/@RequestMapping("/hostkey2")//名称唯一 但 热点规则 必须需要此项配置,无此注解不生效@SentinelResource(value = "hostkey",blockHandler = "fallback_hostkey")public String testHotKey2(@RequestParam(value="p1",required = false) String p1,@RequestParam(value="p2",required = false) String p2){int a = 10/0;return "---- test Hot Key ----";}

重启项目,再次访问:

http://localhost:8500/hostkey2

[发现:]

出现了异常,但未进入blockHandler中。

[如何解决呢?]

@SentinelResource 其实和 @HystrixCommand 类似,拥有一个 fallback!

修改代码:

// 修改sentinel 降级的默认回执方法public String fallback_hostkey(String p1, String p2, BlockException blockException){return "限流咯。。。。";}/*** 热点规则测试项* @param p1* @param p2* @return*/@RequestMapping("/hostkey2")//名称唯一 但 热点规则 必须需要此项配置,无此注解不生效@SentinelResource(value = "hostkey",blockHandler = "fallback_hostkey")public String testHotKey2(@RequestParam(value="p1",required = false) String p1,@RequestParam(value="p2",required = false) String p2){int a = 10/0;return "---- test Hot Key ----";}

重启再次请求:

http://localhost:8500/hostkey2

七、Sentinel系统自适应限流

之前的配置操作,采取的是针对单个请求地址请求别名进行配置的限流操作,sentinel同时也提供了一种很潮流的方式实现配置操作—系统自适应限流

何为系统自适应限流?

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

《系统自适应限流》

文档中,对系统自适应限流有如下几种配置:

阈值类型的含义如下所示:

Load 自适应(仅支持Linux/Unix-like)

系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。(系统核心数*2.5)CPU usage(1.5.0+ 版本

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

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

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

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

配置案例:

配置入口QPS

只配置 QPS 项,其他流控模式未配置。

请求测试:

缓慢请求 /test1

快速请求 /test1

缓慢请求 /test2

快速请求 /test2

八、代码git地址

git地址

以上就是所有内容,学了sentinel的都会对这篇文章赞不绝口的。

----我是“道祖且长”,一个在互联网“苟且偷生”的Java程序员

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。