【】月均活跃用户达1.3亿,B站高可用架构实践( 三 )


在冷却时间后 , 重新判断阈值(CPU>800 ) , 是否持续进入过载保护 。
重试
【】月均活跃用户达1.3亿,B站高可用架构实践
本文插图

流量的走向 , 一般会从 BFE 到 LB(负载均衡)然后经过 API 网关再到 BFF、微服务最后到数据库 , 这个过程要经过非常多层 。
在我们的日常工作中 , 当请求返回错误 , 对于 Backend 部分节点过载的情况下 , 我们应该怎么做?

  • 首先我们需要限制重试的次数 , 以及基于重试分布的策略 。
  • 其次 , 我们只应该在失败层进行重试 , 当重试仍然失败时 , 我们需要全局约定错误码 , 避免级联重试 。
  • 此外 , 我们需要使用随机化、指数型递增的充实周期 , 这里可以参考 Exponential Backoff 和 Jitter 。
  • 最后 , 我们需要设定重试速率指标 , 用于诊断故障 。

【】月均活跃用户达1.3亿,B站高可用架构实践
本文插图

而在客户端侧 , 则需要做限速 。 因为用户总是会频繁尝试去访问一个不可达的服务 , 因此客户端需要限制请求频次 , 可以通过接口级别的 error_details , 挂载到每个 API 返回的响应里 。
超时
【】月均活跃用户达1.3亿,B站高可用架构实践
本文插图

我们之前讲过 , 大部分的故障都是因为超时控制不合理导致的 。 首当其冲的是高并发下的高延迟服务 , 导致 Client 堆积 , 引发线程阻塞 , 此时上游流量不断涌入 , 最终引发故障 。
所以 , 从本质上理解超时它实际就是一种 Fail Fast 的策略 , 就是让我们的请求尽可能消耗 , 类似这种堆积的请求基本上就是丢弃掉或者消耗掉 。
另一个方面 , 当上游超时已经返回给用户后 , 下游可能还在执行 , 这就会引发资源浪费的问题 。
再一个问题 , 当我们对下游服务进行调优时 , 到底如何配置超时 , 默认值策略应该如何设定?
生产环境下经常会遇到手抖或者错误配置导致配置失败、出现故障的问题 。 所以我们最好是在框架层面做一些防御性的编程 , 让它尽可能让取在一个合理的区间内 。
进程内的超时控制 , 关键要看一个请求在每个阶段(网络请求)开始前 , 检查是否还有足够的剩余来处理请求 。
另外 , 在进程内可能会有一些逻辑计算 , 我们通常认为这种时间比较少 , 所以一般不做控制 。
【】月均活跃用户达1.3亿,B站高可用架构实践
本文插图

现在很多 RPC 框架都在做跨进程超时控制 , 为什么要做这个?跨进程超时控制同样可以参考进程内的超时控制思路 , 通过 RPC 的源数据传递 , 把它带到下游服务 , 然后利用配额继续传递 , 最终使得上下游链路不超过一秒 。
应对连锁故障
结合我们上面讲到的四个方面 , 应对连锁故障 , 我们有以下几大关键点需要考虑 。
【】月均活跃用户达1.3亿,B站高可用架构实践
本文插图

第一 , 我们需要尽可能避免过载 。 因为节点一个接一个挂了的话 , 最终服务会雪崩 , 有可能机群都会跟着宕掉 , 所以我们才提到要做自保护 。
第二 , 我们通过一些手段去做限流 。 它可以让某一个 Client 对服务出现高流量并发请求时进行管控 , 这样的话服务也不容易死 。
另外 , 当我们无法正常服务的时候 , 还可以做有损服务 , 牺牲掉一些非核心服务去保证关键服务 , 做到优雅降级 。
第三 , 在重试策略上 , 在微服务内尽可能做退避 , 尽可能要考虑到重试放大的流量倍数对下游的冲击 。
另外还要考虑在移动端用户用不了某个功能的情况下 , 通常会频繁刷新页面 , 这样产生的流量冲击 , 我们在移动端也要进行配合来做流控 。


推荐阅读