服务雪崩
因为服务的提供者的不可用导致上游调用者服务请求积压导致也不可用,继而逐渐影响调用链路上的其他节点都不可用。这个过程称作服务雪崩。
雪崩的原因:
流量激增:
- 激增流量导致系统 CPU / Load 飙高,无法正常处理请求
- 激增流量打垮冷系统(数据库连接未创建,缓存未预热、冷系统本身配置过低)
- 消息投递速度过快,导致消息处理积压
不稳定服务依赖:
- 慢 SQL 查询使得连接池无可用连接,连接池不可用
- 第三方服务不响应,线程池无可用线程,线程池不可用
- 业务调用持续抛出异常
当服务提供者不可用时,会出现大量重试的情况:用户手动触发重试、代码逻辑上重试,最终只会进一步加大请求流量。本质在于调用都是在同步等待调用,大量的重试使得服务提供者本机系统资源耗尽,继而使得服务提供者处于不可用的状态。最终会影响到上游服务以及调用链路上的所有服务节点都变的不可用,这就是雪崩效应。
解决方案
- 稳定性(reliability)
- 恢复性(resilience)
常见的容错机制
- 超时机制:设置请求超时时间,如:connectTimeout
- 服务限流:设置 QPS、线程数阈值,拒绝超出阈值的请求
- 服务熔断:消费者发现远程服务不可用时暂时,标记为关闭就叫做服务熔断。明知一个服务处于不可用而继续进行调用,是没有意义且浪费资源的。
- 服务降级:熔断的后续处理。客户端本地准备一个 fallback 回调,返回一个缺省值,返回如备用接口、缓存数据等。当服务调用熔断的服务时执行改 fallback。一般作用在业务流程中不重要的服务节点。
Sentinel 介绍
官方文档。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
Sentinel 是 Spring Cloud Alibaba 的一个重要组件,同类组件有 Spring Clound 的 Hystrix。与 Hystrix-Dashboard 控制台一样,Sentinel-Dashboard 控制台也可以提供对流量的实时监控、在线维护流量规则、熔断规则等。
流量监控
流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如下图所示:
流量控制有以下几个角度:
- 资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
- 运行指标,例如 QPS、线程池、系统负载等;
- 控制的效果,例如直接限流、冷启动、排队等。
Sentinel 的设计理念是让您自由选择控制的角度,并进行灵活组合,从而达到想要的效果。
熔断降级
除了流量控制以外,降低调用链路中的不稳定资源也是 Sentinel 的使命之一。由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,最终会导致请求发生堆积。这个问题和 Hystrix 里面描述的问题是一样的。
在限制的手段上,Sentinel 和 Hystrix 采取了完全不一样的方法。
Hystrix 通过线程池的方式,来对依赖(在我们的概念中对应资源)进行了隔离。这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本,还需要预先给各个资源做线程池大小的分配。
Sentinel 对这个问题采取了两种手段:
-
通过并发线程数进行限制
和资源池隔离的方法不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。 -
通过响应时间对资源进行降级
除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。
系统负载保护
Sentinel 同时提供系统维度的自适应保护能力。防止雪崩,是系统防护中重要的一环。当系统负载较高的时候,如果还持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用。
针对这个情况,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
Sentinel 中的名词解释
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则
围绕资源的实时状态设定的规则,可以包括:
- 流量控制规则
- 熔断降级规则
- 系统保护规则
所有规则可以动态实时调整。