SpringCloud 06 服务容错 Sentinel
雪崩:一个微小的故障引起系统其他部分出现故障,最终使整个系统不可用。
雪崩一般经历以下三个阶段:
- 实例能力出现过载。可能是 bug 导致性能下降,可能是实例宕机,可能是突发流量,总之实例无法处理如此多请求。
- 服务资源耗尽不可用。过载后,大量请求积压在实例中,迅速消耗服务的CPU,内存,线程等资源。这些资源耗尽,实例出现超时和崩溃。表现为不可用。负载均衡器将请求调度到其他实例,其他实例也同样过载不可用。服务过载。
- 一个服务不可用,服务调用方也出现大量积压请求,同样出现过载。逆向沿着调用链路传播,最终导致系统雪崩。
解决思路:
- 熔断。调用方认为被调用服务过载,则快速返回错误,不执行调用。
- 限流。调用方限定请求量,避免过载。
- 降级。牺牲非核心业务保护核心业务。
- 扩容。增加实例,提升资源。
Sentinel
Sentinel 是服务容错插件。实现流量控制,熔断降级,系统保护等多个功能。
Sentinel 将被保护对象称为资源。资源可以是接口,URI,代码。
外部请求访问资源时,Sentinel 将外部请求包装为 Entry 对象,并交给 slot chain 处理。
slot chain 是典型的责任链模式。
常见的 slot 有:
NodeSelectorSlot构建请求的访问路径,并且串联调用链。
StatisticSlot统计运行期数据,比如接口响应时间,线程数,QPS等。
DegradeSlot判定是否熔断降级。FlowSlot判定限流。
实现ProcessorSlot接口可以自定义slot。
sentinel 流量控制模式:
- 直接流控。当前资源访问压力超出阈值,则限制请求。
- 关联流控。关联资源访问压力超出阈值,则限制请求。如果资源A与资源B争抢资源,比如数据库。而资源A优先级低。如果A的关联资源(B)的访问压力超出阈值,则限制A的请求,把数据库资源让给B。
- 链路流控。如果两个接口(/api/name, /api/overview)都能访问资源。而只想限流其中一个接口。
sentinel 流量控制策略:
- 快速失败。
- warm up。随时间增加流量阈值。
- 排队等待。请求进入等待队列,在等待队列中超时则失败。
@SentinelResource注解的blockHandler属性指定降级方法的名称,它仅在 BlockException 情况下触发。BlockException 是 sentinel 定义的异常类,表示被 slot chain 拦截。对于其他 RuntimeException,需要用 fallback 属性指定降级方法。
sentinel 提供三种熔断规则:
- 异常比例。
- 异常数。
- 慢调用比例。