springcloud入门——Sentinel服务降级
目录
1.Sentinel降级概述
现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。
Sentinel熔断降級会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例高),对这个资的调用进行限制,让请求快速失败,避兔影响到其它的资而导致級联错误。当被降级后,在接下来的时间口之内,对该资源的调用都自动熔断(默认行为是抛出Degradeexception)
(与Hystrix服务熔断类似)
Sentinel服务降级具有以下三个参数:
2.Sentinel降级应用
1.平均响应时间(DEGRADE_GRADE_RT):
当1s内持续进入5个请求;对应时刻的平均响应时间(秒级)均超过阈值( 以ms为单位)。
那么在接下的时间窗口(秒级)之内,对这个方法的调用都会自动地熔断。
Sentinel 默认统计的RT上限是4900 ms,超出此阈值的都会算作4900ms,若需要变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx来配置。
在cloud-8401中控制类编写以下代码进行测试:
被sentinel监控后,新建服务降级:
jmeter压测:
符合触发RT服务降级条件(线程数10>5;响应时间1s>0.2s),固访问将抛出异常:
在未来1S的时间窗口内,断路器打开(保险丝跳闸)微服务不可用,保险丝跳闸断电了后续我停止jmeter,没有这么大的访问量了,断路器关闭(保险丝恢复),微服务恢复OK。
注意:Sentinel 1.7.0才有平均响应时间(DEGRADE_GRADE_RT),Sentinel 1.8.0的没有这项,取而代之的是慢调用比例 (SLOW_REQUEST_RATIO)。
慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
2.异常比例
当资源的每秒请求量 >= 5;并且每秒异常总数占通过量的比值超过阈值之后。
资源进入降级状态,即在接下的时间窗口( DegradeRule中的timeWindow,以s为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.0, 1.0],代表0% -100%。
控制类中修改testD的代码,设置被除数0异常:
新增服务降级规则:
同理,使用jmeter压测。
结论:
按照上述配置,单独访问一次,必然来一次报错一次。
开启jmeter后,直接高并发发送请求,多次调用达到我们的配置条件了。断路器开启(保险丝跳闸),微服务不可用了,不再报错error而是服务降级了。
3.异常数
当资源近1分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若timeWindow
小于60s,则结束熔断状态后码可能再进入熔断状态。
(异常数是按照分钟统计的,时间窗口一定要大于等于60秒。)
还是testD,新增降级规则:
访问http://localhost:8401/testE,第一次访问绝对报错,因为除数不能为零,我们看到error窗口,但是达到5次报错后,进入熔断后降级。
3.Sentinel热点key
热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:
- 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
- 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
兜底方法包括:系统默认(sentinel系统默认的提示: Blocked by Sentinel (flow limiting))和客户自定义(@SentinelResource)
在controller中编写自定义兜底方法及应用的url:
配置热点规则(此处限制第0个参数p1):
只要传值p1参数,访问阈值超过1,返回自定义的兜底方法:
参数例外项
- 普通 - 超过1秒钟一个后,达到阈值1后马上被限流
- 我们期望p1参数当它是某个特殊值时,它的限流值和平时不一样
- 特例 - 假如当p1的值等于5时,它的阈值可以达到200
配置如下:
前提条件 - 热点参数的注意点,参数必须是基本类型或者String
注意:
- @SentinelResource - 处理的是sentinel控制台配置的违规情况,有blockHandler方法配置的兜底处理;
- RuntimeException (比如int age = 10/0),这个是java运行时报出的运行时异常RunTimeException,@SentinelResource不管
更多推荐
所有评论(0)