衡水做网站开发的,软件外包公司,十个知名的跨境电商公司,一个做网站的公司年收入第十七章_Sentinel实现熔断与限流
1.Sentinel介绍
1.1是什么
随着微服务的流行#xff0c;服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点#xff0c;从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
用来代替Hystrix
Sentinel 具有…第十七章_Sentinel实现熔断与限流
1.Sentinel介绍
1.1是什么
随着微服务的流行服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
用来代替Hystrix
Sentinel 具有以下特征:
丰富的应用场景Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景例如秒杀即突发流量控制在系统容量可以承受的范围、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。**完备的实时监控**Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据甚至 500 台以下规模的集群的汇总运行情况。**广泛的开源生态**Sentinel 提供开箱即用的与其它开源框架/库的整合模块例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。**完善的 SPI 扩展点**Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 的主要特性 1.2Hystrix与Sentinel比较
Hystrix
需要我们程序员自己手工搭建监控平台没有一套web界面可以给我们进行更加细粒度化得配置流控、速率控制、服务熔断、服务降级
Sentinel
单独一个组件可以独立出来。直接界面化的细粒度统一配置。
约定 配置 编码
都可以写在代码里面但是我们本次还是大规模的学习使用配置和注解的方式尽量少写代码
2.Sentinel下载安装运行
官方文档Spring Cloud Alibaba Reference Documentation (spring-cloud-alibaba-group.github.io)
服务使用中的各种问题
服务雪崩服务降级服务熔断服务限流
Sentinel 分为两个部分
核心库Java 客户端不依赖任何框架/库能够运行于所有 Java 运行时环境同时对 Dubbo / Spring Cloud 等框架也有较好的支持。控制台Dashboard基于 Spring Boot 开发打包后可以直接运行不需要额外的 Tomcat 等应用容器。
2.1安装步骤
1下载
地址 2运行命令
前提java8环境OK 8080端口不能被占用
运行命令
java -jar sentinel-dashboard-1.7.1.jar3访问sentinel管理界面 3.初始化演示工程
3.1新建cloudalibaba-sentinel-service8401
1pom
dependencies!-- 后续做Sentinel的持久化会用到的依赖--dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId/dependency!-- springcloud alibaba nacos 依赖,Nacos Server 服务注册中心 --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependency!--openfeign--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency!-- springboot整合Web组件 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependency!-- 日常通用jar包 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-devtools/artifactIdscoperuntime/scopeoptionaltrue/optional/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependency!-- 引入自己定义的api通用包可以使用Payment支付Entity --groupIdspringcloud/groupIdartifactIdcloud-api-commons/artifactIdversion${project.version}/version/dependency/dependencies2yml 3主启动 4controller层 5测试
启动成功之后Sentinel控制台空空如也
原因Sentinel采用懒加载执行一次即可
localhost:8401/testB 4.流控规则
4.1基本介绍 1解释说明—重要
资源名唯一名称默认请求路径针对来源sentinel可以针对调用者进行限流填写微服务名默认default不区分来源阈值类型/单机值 QPS每秒钟的请求数量当调用该api就QPS达到阈值的时候进行限流线程数当调用该api的线程数达到阈值的时候进行限流 是否集群不需要集群流控模式 直接api达到限流条件时直接限流。分为QPS和线程数关联当关联的资源达到阈值时就限流自己。链路只记录指定链路上的流量指定资源从入口资源进来的流量如果达到阈值就进行限流【api级别的针对来源】 流控效果 快速失败直接抛异常warm up根据codeFactor冷加载因子默认3的值从阈值codeFactor经过预热时长才达到设置的QPS阈值排队等待匀速排队让请求以匀速通过阈值类型必须设置为QPS否则无效
2QPS和线程数的区别
QPS 类似于银行的保安所有的请求到Sentinel 后他会根据阈值放行超过报错线程数类似于银行的窗口所有的请求会被放进来但如果阈值设置为1那么其他的请求就会报错也就是银行里只有一个窗口一个人在办理业务中其他人跑过来则会告诉你“现在不行没到你” 3重要属性 4.2流控模式
1直接—默认
配置及说明表示1秒钟内查询1次就是OK若超过次数1就直接-快速失败报默认错误 测试快速点击访问http://localhost:8401/testA 2关联 解释关联的资源达到阈值时就限流自己 配置及说明当关联资源/testB的qps阀值超过1时就限流/testA的Rest访问地址 使用postman新建多线程集合组 运行后发现testA挂了点击访问http://localhost:8401/testA 3链路
只记录指定链路上的流量指定资源从入口资源进来的流量如果达到阈值就进行限流)【API级别的针对来源】
4.3流控效果
1快速失败
直接失败抛出异常Blocked by Sentinel (flow limiting)
2预热
Warm UpRuleConstant.CONTROL_BEHAVIOR_WARM_UP方式即预热/冷启动方式。当系统长期处于低水位的情况下当流量突然增加时直接把系统拉升到高水位可能瞬间把系统压垮。通过冷启动让通过的流量缓慢增加在一定时间内逐渐增加到阈值上限给冷系统一个预热的时间避免冷系统被压垮。详细文档可以参考 流量控制 - Warm Up 文档具体的例子可以参见 WarmUpFlowDemo
通常冷启动的过程系统允许通过的 QPS 曲线如下图所示 3WarmUp配置
默认 coldFactor 为 3即请求QPS从(阈值 / 3) 开始经多少预热时长才逐渐升至设定的 QPS 阈值
系统配置系统初始化的阀值为10 / 3 约等于3即阀值刚开始为3然后过了5秒后阀值才慢慢升高恢复到10。效果为开始访问 localhost:/testA 时每秒请求别超过10/3个才能正常访问5秒后可以接受的请求可以达到每秒10次。
应用场景
秒杀系统在开启的瞬间会有很多流量上来很有可能把系统打死预热方式就是把为了保护系统可慢慢的把流量放进来慢慢的把阀值增长到设置的阀值
4排队等待
匀速排队让请求以均匀的速度通过阀值类型必须设成QPS否则无效
设置含义/testA每秒1次请求超过的话就排队等待等待的超时时间为20000毫秒 说明匀速排队阈值必须设置为QPS
匀速排队RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER方式会严格控制请求通过的间隔时间也即是让请求以均匀的速度通过对应的是漏桶算法。详细文档可以参考流量控制 - 匀速器模式 具体的例子可以参见 PaceFlowDemo。
5.降级规则
5.1熔断降级概述
除了流量控制以外对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块可能是另外的一个远程服务、数据库或者第三方 API 等。例如支付的时候可能需要远程调用银联提供的 API查询某个商品的价格可能需要进行数据库查询。然而这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况请求的响应时间变长那么调用服务的方法的响应时间也会变长线程会产生堆积最终可能耗尽业务自身的线程池服务本身也变得不可用。
现代微服务架构都是分布式的由非常多的服务组成。不同服务之间相互调用组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定就可能会层层级联最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级暂时切断不稳定调用避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段通常在客户端调用端进行配置。
5.2降级策略介绍 RT平均响应时间秒级 平均响应时间超出阈值且在时间窗口内通过的请求5两个条件同时满足后触发降级 窗口期过后关闭断路器 RT最大4900更大的需要通过-Dcsp.sentinel.statistic.max.rtXXXX才能生效 异常比列秒级 QPS 5且异常比例秒级统计超过阈值时触发降级时间窗口结束后关闭降级 异常数**分钟级** 异常数分钟统计超过阈值时触发降级时间窗口结束后关闭降级
5.3RT
1介绍
平均响应时间(DEGRADE_GRADE_RT)当1s内持续进入5个请求对应时刻的平均响应时间秒级均超过阈值 count以ms为单位那么在接下的时间窗口DegradeRule中的timeWindow以s为单位之内对这个方法的调用都会自动地熔断(抛出DegradeException )。注意Sentinel 默认统计的RT上限是4900 ms超出此阈值的都会算作4900ms若需要变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rtxxx来配置。 注意Sentinel 1.7.0才有平均响应时间DEGRADE_GRADE_RTSentinel 1.8.0的没有这项取而代之的是慢调用比例 (SLOW_REQUEST_RATIO)。 慢调用比例 (SLOW_REQUEST_RATIO)选择以慢调用比例作为阈值需要设置允许的慢调用 RT即最大的响应时间请求的响应时间大于该值则统计为慢调用。当单位统计时长statIntervalMs内请求数目大于设置的最小请求数目并且慢调用的比例大于阈值则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态HALF-OPEN 状态若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断若大于设置的慢调用 RT 则会再次被熔断。熔断降级 · alibaba/Sentinel Wiki · GitHub
如图为Sentinel1.7.0的降级规则为RT策略流程图 2实操
在controller中加入textD 配置当1s内持续进入5个请求默认5个请求对应时刻的平均响应时间秒级均超过0.2s count以ms为单位,那么在接下的时间窗口1s之内对这个方法的调用都会自动地熔断 Jmeter压测永远一秒钟打进来10个线程大于5个调用testD 测试 5.4异常比例
1介绍
异常比例(DEGRADE_GRADE_EXCEPTION_RATIO)当资源的每秒请求量 5并且每秒异常总数占通过量的比值超过阈值 DegradeRule中的 count之后资源进入降级状态即在接下的时间窗口( DegradeRule 中的 timeWindow以s为单位之内对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.0, 1.0]代表0% -100%。
注意与Sentinel 1.8.0相比有些不同Sentinel 1.8.0才有的半开状态Sentinel 1.8.0的如下
异常比例 (ERROR_RATIO)当单位统计时长statIntervalMs内请求数目大于设置的最小请求数目并且异常的比例大于阈值则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态HALF-OPEN 状态若接下来的一个请求成功完成没有错误则结束熔断否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0]代表 0% - 100%。熔断降级 · alibaba/Sentinel Wiki · GitHub
接下来讲解Sentinel 1.7.0
如图为Sentinel1.7.0的降级规则为异常比例策略流程图 2实操
在controller中加入textE 配置说明若满足1秒访问testE资源并且有异常的访问次数超过百分之20的话将进行服务降级经过1秒的时间窗口之后关闭服务降级 测试 单独访问一次localhost:8401/testE Jmeter压测
结论
按照上述配置单独访问一次必然来一次报错一次(int age 10/0)调一次错一次开启jmeter后直接高并发发送请求多次调用达到我们的配置条件了。
断路器开启(保险丝跳闸)微服务不可用了不再报错error而是服务降级了
5.5异常数
1介绍
异常数( DEGRADE_GRADF_EXCEPTION_COUNT )当资源近1分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的若timeWindow小于60s则结束熔断状态后可能再进入熔断状态。
说明假设时间窗口期为10秒设置的异常数不能超过5统计阶段第1秒的时候有5个异常服务熔断后进入时间窗口期时间窗口期结束但是一分钟还没结束那么此时的异常数还是5个又进入熔断状态。
注意与Sentinel 1.8.0相比有些不同Sentinel 1.8.0才有的半开状态Sentinel 1.8.0的如下
异常数 (ERROR_COUNT)当单位统计时长默认一分钟内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态HALF-OPEN 状态若接下来的一个请求成功完成没有错误则结束熔断否则会再次被熔断。
如图为Sentinel1.7.0的降级规则为异常数策略流程图 由于异常数是按照分钟统计的时间窗口一定要大于等于60秒。
2实战 测试连续5次之后 6.热点key限流
6.1基本介绍
1热点介绍
何为热点热点即经常访问的数据很多时候我们希望统计或者限制某个热点数据中访问频次最高的 Top N 数据并对其访问进行限流或者其它操作
商品 ID 为参数统计一段时间内最常购买的商品 ID 并进行限制用户 ID 为参数针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数并根据配置的限流阈值与模式对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制仅对包含热点参数的资源调用生效。 2兜底方法介绍
兜底方法分为 系统默认 和 客户自定义 两种。
之前的案例限流出问题后都是用sentinel系统默认的提示: Blocked by Sentinel (flow limiting)
我们能不能自定类似hystrix某个方法出问题了就找对应的兜底降级方法?
结论 - 从HystrixCommand到SentinelResource
6.2实操
在controller中加入
说明SentinelResource(value “testHotKey”,blockHandler “deal_testHotKey”)方法 testHotKey 里面第一个参数只要QPS超过每秒1次马上降级处理异常用了我们自己定义的兜底方法。 配置说明在1秒的窗口时间内访问次数超过1的话就开启限流 测试快速点击携带参数p1 测试快速点击携带参数p2
6.3参数例外项
上述案例演示了第一个参数p1当QPS超过1秒1次点击后马上被限流
特例情况我们期望p1参数当它是某个特殊值时它的限流值和平时不一样
特例假如当p1的值等于5时它的阈值可以达到200 热点参数的注意点参数必须是基本类型或者String 配置如下 快速点击测试当p1参数为5时候 7.系统规则
7.1各项配置参数说明 7.2SentinelResource配置
pom文件增加 !-- 引入自己定义的api通用包可以使用payment对象--dependencygroupIdspringcloud/groupIdartifactIdcloud-api-commons/artifactIdversion1.0-SNAPSHOT/version/dependency1按自定义资源名称限流
①controller层
RestController
public class RateLimitController {GetMapping(/byResource)SentinelResource(value byResource,blockHandler handleException)public CommonResult byResource(){return new CommonResult(200,按资源名称限流测试OK,new Payment(2020L,serial001));}public CommonResult handleException(BlockException exception){return new CommonResult(444,exception.getClass().getCanonicalName()\t 服务不可用);}}②流控配置 ③测试
快速点击测试localhost:8401/byResource ④额外问题
此时关闭服务8401查看Sentinel控制台流控规则消失即为临时 2按url地址限流
①controller层 GetMapping(/rateLimit/byUrl)public CommonResult byUrl(){return new CommonResult(200,按url限流测试,new Payment(2020L,serial002));}②流控配置 ③测试
快速点击localhost:8401/rateLimit/byUrl 3上面兜底方案面临的问题
系统默认的没有体现我们自己的业务要求依照现有条件我们自定义的处理方法又和业务代码耦合在一块不直观每个业务方法都添加一个兜底的那代码膨胀加剧局统一的处理方法没有体现
4客户自定义限流处理逻辑
①自定义限流处理逻辑CustomerBlockHandler
public class CustomerBlockHandler {public static CommonResult handlerException1(BlockException exception){return new CommonResult(4444,按用户自定义,global handlerException.......1);}public static CommonResult handlerException2(BlockException exception){return new CommonResult(4444,按用户自定义,global handlerException.......2);}
}②controller层
//根据用户自定义流控规则进行限流且实现全局流控规则GetMapping(/rateLimit/customerBlockHandler)SentinelResource(value customerBlockHandler,blockHandlerClass CustomerBlockHandler.class,blockHandler handlerException2)public CommonResult customerBlockHandler(){return new CommonResult(200,按用户自定义,new Payment(2020L,serial003));}③配置
注意两个配置不能同时生效 按自定义资源名流控 按url地址流控 ④测试
按自定义资源名称流控配置 按url地址流控配置 ⑤结论
在设置了 URL地址流控的前提下设置按资源名称流控无效
即URL地址流控优先级大于资源名称流控
7.3更多注解属性说明 8.服务熔断功能
sentinel整合ribbonspenFeignfallback
8.1新建实验环境
1Ribbon系列-服务提供者9003/9004
启动nacos和sentinel新建cloudalibaba-provider-payment9003/9004两个服务提供者
①pom
dependencies!-- springcloud alibaba nacos 依赖 --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependency!-- springboot整合Web组件 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependency!-- 日常通用jar包 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-devtools/artifactIdscoperuntime/scopeoptionaltrue/optional/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependency!-- 引入自己定义的api通用包可以使用Payment支付Entity --groupIdcom.atguigu.springcloud/groupIdartifactIdcloud-api-commons/artifactIdversion${project.version}/version/dependency/dependencies②yml ③主启动 ④controller层 2Ribbon系列-消费者84
新建cloudalibaba-consumer-nacos-order84
①pom dependencies!-- 后续做Sentinel的持久化会用到的依赖 --dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId/dependency!-- sentinel --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId/dependency!-- springcloud alibaba nacos 依赖 --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency!-- springboot整合Web组件 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependency!-- 日常通用jar包 --dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-devtools/artifactIdscoperuntime/scopeoptionaltrue/optional/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependency!-- 引入自己定义的api通用包可以使用Payment支付Entity --groupIdcom.atguigu.springcloud/groupIdartifactIdcloud-api-commons/artifactIdversion${project.version}/version/dependency/dependencies②yml ③主启动 ④配置类 ⑤controller层
3针对消费者84有无配置fallback和blockHandler
①无配置 测试 测试id为4 测试id为5
②配置fallback ③配置blockHandler sentinel新增服务降级规则是服务降级、是服务降级 若一分钟内异常数超过2则开启断路器在80秒的时间窗口内使用自定义的兜底方法80秒一过恢复默认的异常报错页面 测试 ④同时配置fallback和blockHandler 测试 第一、二次访问异常路径显示的是配置fallback的兜底方法 第三次访问异常路径显示的是配置blockHandler的方法
8.2忽略异常
84服务消费者的controller层 测试
9.sentinel整合feign
9.1步骤
1pom !-- sentinel整合openfeign--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency2yml 3主启动
主启动激活feign 4feign指定寻找的服务 5controller层 6测试
测试一 测试二模拟feign调用远程服务超时feign默认1秒
9003和9004服务提供者controller新增 测试时发现如果只给一个微服务加延时另一个不加会一直调用没有延时的微服务所以要么两个都加延时或者停掉一个 测试结果服务降级 10.Sentinel持久化
目前的sentinel 当重启以后数据都会丢失和 nacos 类似原理。需要持久化。它可以被持久化到 nacos 的数据库中。
10.1步骤
1pom
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId
/dependency2yml 3nacos新增配置 resource资源名称 limitApp来源应用 grade阈值类型0表示线程数1表示QPS count单机阈值 strategy流控模式0表示直接1表示关联2表示链路 controlBehavior:流控效果0表示快速失败1表示Warm Up,2表示排队等待 cIusterM0de是否集群 总结: 就是在 sentinel 启动的时候去 nacos 上读取相关规则配置信息实际上它规则的持久化就是第三步粘贴到nacos上保存下来就算以后在 sentinel 上面修改了重启应用以后也是无效。 4测试
快速点击 查看规则