雪崩问题:微服务之间相互调用,因为调用链路中一个服务故障,引起了整个链路都无法访问的情况
如何避免因服务故障引起的雪崩问题?
- 超时处理
- 线程隔离
- 降级熔断
如何避免因瞬间高并发流量而导致服务故障?
- 流量控制
服务保护技术对比
Sentinel | Hystrix | |
---|---|---|
隔离策略 | 信号量隔离 | 线程池/信号量隔离 |
熔断降级策略 | 基于慢调用比例或异常比例 | 基于失败比率 |
限流 | 基于QPS,支持基于调用关系的限流 | 有限的支持 |
流量整形 | 支持慢启动,匀速排队模式 | 不支持 |
控制台 | 开箱即用,可配置规则,查看秒级监控,机器发现等 | 不完善 |
使用Sentinel
- 引入依赖
- yml文件配置控制台地址
- 访问微服务任意端点,触发Sentinel监控
流控模式
- 直接模式:对当前资源限流
- 热点参数限流:分别统计参数值相同的请求,判断是否超过QPS阈值,可对指定参数限流
(注:热点参数限流对默认的SpringMVC资源无效,需要加上@SentinelResource注解) - 关联模式:高优先级资源触发阈值,对低优先级资源限流
- 链路模式:阈值统计时,只统计从指定资源进入当前资源的请求,是对请求来源的限流
- Sentinel默认只标记Controller中的方法为资源,如需要标记其他方法,需要利用@SentinelResoucrce注解
- Sentinel默认会将Controller方法做context整合,导致链路模式的流控失效,需要修改yml文件配置来关闭context整合
流控效果
- 快速失败:QPS超过阈值时,拒绝新的请求
- warm up:QPS超过阈值时,拒绝新的请求;QPS阈值是逐渐提升的,可以避免冷启动时高并发导致服务宕机
- 排队等待:请求会进入队列,按照阈值允许的时间间隔依次执行请求;如果请求预期等待时长大于超时时间,直接拒绝
Feign整合Sentinel步骤
- 在application.yml中配置:feign.sentinel.enable=true
- 给FeignClient编写FallbackFactory并注册为Bean
- 将FallbackFactory配置到FeignClient
Sentinel雪崩解决方案(对客户端(调用方)的保护)
- 线程隔离(舱壁模式)
- 熔断降级
线程隔离
- 信号量隔离
优点:轻量级,无额外开销
缺点:不支持主动超时,不支持异步调用
适用场景:高频调用,高扇出 - 线程池隔离:基于线程池模式,有额外开销,但隔离控制更强
优点:支持主动超时,支持异步调用
缺点:线程的额外开销比较大
适用场景:低扇出
熔断降级
- 慢调用比例:超过指定时长的调用为慢调用,统计单位时长内慢调用的比例,超过阈值则熔断
- 异常比例:统计单位时长内异常调用的比例,超过阈值则熔断
- 异常数:统计单位时长内异常调用的次数,超过阈值则熔断
授权规则
获取请求来源的接口:RequestOriginParser
自定义异常
处理BlockException的接口:BlockExceptionHandler
异常 | 说明 |
---|---|
FlowException | 限流异常 |
ParamFlowException | 热点参数限流异常 |
DegradeException | 降级异常 |
AuthorityException | 授权规则异常 |
SystemBlockException | 系统规则异常 |
规则持久化
Sentinel有三种配置管理模式
- 原始模式:保存在内存(Sentinel默认模式)
- pull模式:保存在本地文件或数据库,定时去读取
- push模式:保存在nacos,监听变更,实时更新