API 调用稳定性被认为是数据服务最重要的指标。 该指标的影响因素多种多样,袋鼠云数据服务平台DataAPI不仅多次对调用的性能和稳定性进行压力测试和优化,还提供了多种配置项优化方式供客户自行调优。 但是,当遇到意外的大量流量或其他突发情况时,您仍然会遇到 API 调用失败的情况。
当流量持续增长,达到或超过服务本身的承载范围时,建立系统业务的自我保护机制非常重要。 DataAPI是一个袋鼠云数据服务平台,结合API调用和微服务流量控制的概念,引入熔断降级功能,最大程度保证API调用的稳定性和系统可用性。
本文希望通过最通俗的解释和合适的例子,带大家了解什么是熔断降级。
一般来说,在微服务系统的流量保护方面,会提到三种方法:限流、断路和降级,这实际上是系统容错的重要设计模式。
速率限制。 限流是一种限制请求频率和系统内部某些功能执行的措施,以防止整个系统因突然的流量激增而不可用。 限速主要是一种防御和保护手段,从流量源头控制流量,避免出现问题。
融合。 熔断机制是一种自动响应机制,当流量过大或下游服务出现问题时,可以自动断开与下游服务的交互,以防止故障进一步蔓延。 同时,熔断机制还可以自诊断下游系统的错误是否得到纠正,或者上游流量是否降低到正常水平,实现自我恢复。
熔断机制更像是一种自动修复方法,当服务无法支持大量请求或其他服务故障时,可能会发生这种情况,可以对请求进行限制,同时可以尝试恢复。
服务降级。 主要针对非核心业务功能,如果核心业务流程超过预估峰值,则需要节流。 降级通常考虑分布式系统的完整性,并切断来自源的流量。 降级更像是一种估算方式,在预测流量峰值的前提下,通过配置功能提前降低业务体验,或者暂停辅助功能,保证系统主要流程功能的平滑响应。
节流和断路器也可以看作是服务降级的一种手段。 在微服务架构下,服务与服务之间的调用通常以流量为中心,开发者需要从流量路由、流量控制、流量整形、断路器降级、系统自适应过载保护、热点流量保护等多个维度保障微服务的稳定性。 其中,熔断器降级倾向于保证微服务调用链路中关键链路或关键服务的稳定性。
如下图所示,当 Service 异常不可用时,servicea、b、g、f 都会受到影响,如果不加以控制,最终可能会使整个微服务瘫痪。 断路器的作用是在服务服务达到特定错误阈值后停止调用服务如果降级,您将返回开发人员自定义的降级内容,以确保链接的整体可用性。
袋鼠云数据服务平台DataAPI目前提供了三种熔断策略,每个API可以且只能关联一个熔断策略,策略类型为:
慢请求率
如果选择慢调用比例作为阈值,则需要设置允许的慢调用RT(即最大响应时间),如果请求的响应时间大于此值,则计为慢调用。 如果每个 statintervalms 的请求数大于最小请求数,且慢调用占比大于阈值,则请求将在随后的熔断持续时间内自动熔断。
熔断时间过后,熔断器将进入检测恢复状态(半开状态),如果下一个请求的响应时间小于设置的慢呼叫RT,则断路器将终止,如果慢呼叫RT大于设置的慢呼叫RT,则再次熔断。
错误率
如果 statintervalms 周期内的请求数大于最小请求数,且异常占比大于阈值,则在随后的熔断持续时间内自动中断请求。
熔断时间过后,熔断器将进入检测恢复状态(半开状态),如果下一个请求成功完成(无错误),熔断器将终止,否则将再次熔断。 异常比率的阈值范围为 [0.]。0, 1.0],代表 0% -100%。
错误计数
当单位统计周期内的异常数量超过阈值时,自动执行熔断。 熔断时间过后,熔断器将进入检测恢复状态(半开状态),如果下一个请求成功完成(无错误),熔断器将终止,否则将再次熔断。
接下来,我们将通过实例介绍断路器退化在袋鼠云数据服务平台dataapi中的应用。
数据业务的熔断降级是基于Sentinel框架实现的。 Sentinel 对资源的定义更多是服务级别,但它也提供了指定或内容的资源定义。 因此,DataAPI 将 APIID 定义为确定熔断阈值和实现特定熔断器动作的唯一资源。 同时,通过控制资源名称的生成规则,将测试 API 和形式化 API 与环境隔离开来。
在开发和实现过程中,最大的难点是 Sentinel 原生支持限流策略的集群控制,但不支持熔断策略的集群控制。 DataAPI采用的方法是利用主节点实现集群控制,主要有以下两点。
如何仅在主节点上加载断路器规则。
首先,熔断策略是通过基于内存的 degraderulemanager 加载的,由于它是基于内存的,所以需要做一个持久化操作,否则程序重启规则会被清空。 本示例中,MySQL用于创建熔断规则表,用于修改规则详情。
其次,在启动时,通过 Nacos 获取网关实例列表,选择主节点,调用 Nacos 的 NamingServicegetAllInstance 方法获取所有网关实例。 选择第一个健康 Gateway 实例作为主节点,将主节点的 IP 信息以 key value 的形式存储在 Redis 中,重选主节点时会更新 Redis key。
即使当前主节点宕机,您也可以获取幸存的节点实例,每分钟通过定时器重新选择主节点一次,以保证高可用。 当主节点发生变化时,它也会向所有节点发送 Redis 通知,新的主节点会从 MySQL 获取最新的熔断策略并将其加载到内存中,但此操作会清除之前的流量统计信息,并且会重置时间窗口。
最后,如何将策略的修改同步到主节点。 数据服务采用Redis通道通知方式,每个网关监听通道消息,只有确定当前节点为主节点的网关才会执行内存规则的加载操作。
集群阈值确定。
集群内所有示例均正常执行 API 请求,只有阈值判断才会向主节点发送 HTTP 请求进行判断,并返回是否通过的结果,整体工作流程图如下:
阈值确定有两种模式:
错误模式,也可以分解为错误数或错误率。
慢调用模式:指慢调用请求的占比。
由于主节点被确定为实例B,但错误发生在实例A C中,因此需要手动对实例B产生异常或慢调用。 当节点请求异常并且主节点收到异常标志时,它会手动抛出异常,此时可以感知哨兵,异常数将增加 1。 慢调用是通过修改请求的 complatetime 来实现的,以便计数器可以判断慢调用。
用于在 API 编辑页面配置降级内容,配置条件是需要先配置熔断策略,当熔断器开启时,网关会返回一个完全用户自定义的降级内容,必须是 JSON 格式。
降级主要解决资源不足和访问增加的矛盾,在资源有限的情况下可以应对高并发和大量请求。 特别是当API配置无法承载大量流量时,在资源有限的情况下,为了达到上述效果,需要限制一些服务功能但并非完全不可用,系统会返回预设值,保证整个系统能够流畅运行。
降级**的实现比较简单,判断条件生效后,可以通过重写serverwebexchange对象的响应来完成。