微服务架构体系的深度治理 什么是架构体系?( 四 )


接下来再看看集群限流 , 集群限流的情况要更复杂一些 , 首先在各个微服务节点上要有一个计数器 , 对单位时间片内的调用进行计数 , 计数值会被定期的汇总到日志中心 , 由统计分析器进行统一汇总 , 算出这个时间片的总调用量 , 集群限流分析器会拿到这个总调用量 , 并和预先定义的限流阈值进行比对 , 计算出一个限流比例 , 这个限流比例会通过服务注册中心下发到各个服务节点上 , 服务节点基于限流比例会各自算出当前节点对应的最终限流阈值 , 最后利用单机限流进行流控 。
我们可以看到 , 这是一套环环相扣的、各环节紧密协作配合的技术体系 。 单纯拎出一个点来看 , 实现技术都不麻烦 , 但要构建起这么一套贯穿整个技术栈的技术体系 , 则需要有一套统一的技术标准 , 各个环节都需要遵循这套标准 , 对不符合标准的应用还要推动其进行改造 , 才能保证标准落地 , 有了标准之后才能推动各环节一点一点的改造构建起这套限流技术体系 , 所以构建服务限流能力的难点 , 一在于标准化 , 二在于体系化 。
另外 , 限流一大原则是限流动作尽量前置 , 毕竟被限制的流量注定要被“抛弃” , 越早处理越好 , 免得无谓的消耗资源 。
【集群容错】
接下来再来看看集群容错 , 集群容错是微服务集群高可用的保障 , 它有很多策略可供选择 , 包括:

  • 快速失败(Failfast)
  • 失败转移(Failover)
  • 失败重试(Failback)
  • 聚合调用(Forking)
  • 广播调用(Broadcast)
不管用哪种集群容错策略 , 一定要注意重试的次数 , 尤其是线上负载已经很高的时候 , 这时候如果重试次数太多 , 一方面 , 会推高服务被调用方的负载及并发 , 另外一方面 , 会导致服务调用方的调用延时增长 , 双重因素叠加之下 , 最终极可能导致“服务雪崩” , 导致集群被“击穿” 。
所以 , 在使用集群容错的时候 , 一定要设置最大重试次数 。
【服务降级】服务降级和服务限流类似 , 也是微服务集群自我保护的机制 , 一般在线上动用服务降级手段的时候 , 都是线上比较危急的时候 , 生死存亡了 , 这时候留给你思考和反应的时间已经不多 , 所以在使用服务降级之前一定要做好预案 , 你要提前梳理出核心业务链路和非核心业务链路 , 然后通过降级开关一键把部分或所有非核心链路降级 , 这样才能救命 。
服务降级也有很多手段可以使用 , 包括:
  • 容错降级
  • 静态返回值降级
  • Mock降级
  • 备用服务降级
我们常说的熔断 , 本质上也是容错降级策略的一种 , 只不过它比一般容错降级提供了更为丰富的容错托底策略 , 支持半开降级及全开降级模式 。 构建服务降级能力也和限流机制类似 , 同样需要坚持标准化和体系化 。
【故障定界定位】线上的故障定界定位应该是我们每天做的最多的事情 。 分布式环境下的故障定界定位 , 最有效的工具就是动态调用链路跟踪 , 这应该是没有疑义的 , 不管你是使用开源的Zipkin , SkyWalking、PinPoint、CAT , 还是使用商用的听云、AppDynamic或NewRelic等等 。
调用链本质上也是基于日志 , 只不过它比常规的日志更重视日志之间的关系 。 在一个请求刚发起的时候 , 调用链会赋予它一个跟踪号(traceID) , 这个跟踪号会随着请求穿越不同的网络节点 , 并随着日志落盘 , 日志被收集后 , 可以根据traceID来对日志做聚合 , 找到所有的关联日志 , 并按顺序排序 , 就能构建出这个请求跨网络的调用链 , 它能详细描述请求的整个生命周期的状况 。
动态调用链要用的好一定是需要和监控大盘相结合 。 介绍一下我们的使用经验 , 我们在很早之前就构建了动态调用链跟踪体系 , 在我们的监控大盘上有很多的点可以进入调用链:
1、我们有一个单位时间段内异常最多服务的TopN排序列表 , 点击列表上的任何一个服务 , 会打开这个服务这个时间段内所有异常的列表 , 再点击列表上的每一个异常 , 就会打开这个异常所属调用链 , 进行故障分析 。
2、可以利用监控大盘 , 监控大盘上有很多“毛刺” , 这些都是系统的一些异常点 , 点击任何一个“毛刺” , 会将“毛刺”所在时间段内的请求以“散点”的形式列出(可能会基于请求数量做抽样) , “散点”的颜色代表了不同的状态 , 有的成功 , 有的失败 。 点击任何一个“散点” , 就可以进入这个请求对应的调用链 。

推荐阅读