雪崩问题
微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用
解决雪崩问题的常见方式有四种(前三种避免故障传递,流量控制预防故障发生):
- 超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待
- 舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat资源,因此也叫线程隔离
- 熔断降级:由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求
- 流量控制:限制业务访问的QPS(每秒钟请求数量),避免服务因流量的突增而故障
服务保护技术对比(Sentinel与Hystrix)
Sentinel | Hystrix | |
---|---|---|
隔离策略 | 信号量隔离 | 线程池隔离/信号量隔离 |
熔断降级策略 | 基于慢调用比例或异常比例 | 基于失败比率 |
实时指标实现 | 滑动窗口 | 滑动窗口(基于RxJava) |
规则配置 | 支持多种数据源 | 支持多种数据源 |
扩展性 | 多个扩展点 | 插件的形式 |
基于注解的支持 | 支持 | 支持 |
限流 | 基于QPS,支持基于调用关系的限流 | 有限的支持 |
流量整形 | 支持慢启动、匀速排队模式 | 不支持 |
系统自适应保护 | 支持 | 不支持 |
控制台 | 开箱即用,可配置规则、查看秒级监控、机器发现等 | 不完善 |
常见框架适配 | Servlet、Spring Cloud、Dubbo、gRPC等 | Servlet、Spring Cloud Netflix |
安装Sentinel控制台
- 运行jar包
- 访问页面,默认账号密码为sentinel
- 通过配置修改
配置项 | 默认值 | 说明 |
---|---|---|
server.port | 8080 | 服务端口 |
sentinel.dashboard.auth.username | sentinel | 默认用户名 |
sentinel.dashboard.auth.password | sentinel | 默认密码 |
- 启动时修改
1 | java -jar sentinel-dashboard-1.8.1.jar -Dserver.port=8090 |
微服务整合Sentinel
- 引入sentinel依赖
1 | <dependency> |
- 配置控制台地址
1 | spring: |
- 访问微服务任意端点,触发sentinel监控
Sentinel限流规则
簇点链路
项目内的调用链路,链路中被监控的每个接口就是一个资源。默认情况下Sentinel会监控SpringMVC每一个端点
在Sentinel控制台设置流控规则
- 设置QPS,并使用Apache JMeter测试
- 高级配置:流控模式、流控效果
流控模式:直接、关联、链路
- 直接:默认模式,统计当前资源请求,触发阈值对当前资源限流
- 关联:统计与当前资源相关的另一个资源,触发阈值对当前资源限流(A触发阈值对B限流),如触发修改订单阈值,对查询订单限流
- 链路:只统计从指定链路访问到本地的资源的请求,触发阈值时,对指定链路限流
流控效果,请求达到流控阈值时应该采取的措施,包括三种:快速失败、warm up、排队等待
- 快速失败:达到阈值后,新的请求立即被拒绝抛出FlowException异常
- warm up:预热模式,对超出阈值的请求同样拒绝,但这种模式的阈值会动态变化,从小增大到最大阈值
- 排队等待:让所有请求按照先后次序排队执行,间隔不小于指定时常
添加限流方法
Sentinel默认只标记Controller中的方法为资源,如果要标记其它方法,需要利用@SentinelResource注解
Sentinel默认会将Controller方法做context整合,导致链路模式的流控失效,需要修改application.yml
1 | spring: |
流控效果-warm up
应对服务冷启动的一种方案,请求阈值初始值为threshold/coldFactor,持续指定时长后,逐渐提高到threshold,coldFactor(冷启动因子)默认值为3
流控效果-排队等待
让所有请求进入一个队列中,然后按着阈值允许的时间间隔依次执行。后来的请求必须等待前面执行完成,如果请求预期时间超出最大时长,则会被拒绝
- 例如,QPS=5,也就是每200ms处理一个请求。timeout=2000,意味着等待超过2000ms就会抛出异常
热点参数限流
分别统计与设定参数值相同的请求,判断是否超过QPS阈值
- 例如参数索引为0,单机阈值为5,统计窗口时长为1,含义为:对当前资源0号参数(第一个参数)的请求做统计,每1秒的请求数量不超过5
- 高级选项可以对部分参数做例外配置