服务容错

容错性设计不能妥协源于分布式系统的本质是不可靠的

容错策略

面对故障,我们该做些什么

  • 故障转移(Failover):当对某些服务的调用失败 转而调用该服务的其他副本
    • 这种重试策略应该要有一定的阈值 过度的重试反而可能让系统处于更加不利的状况
  • 快速失败(Failfast):对于非幂等的服务调用失败 就应该直接使用失败而非重试来解决
  • 安全失败(Failsafe):对于不在链路主线的服务调用 如日志 扩展点等 这些服务的结果不参与最终运算 即使失败了 也可以当做正确来返回
  • 沉默失败(Failsilent):如果对于某个服务的调用大量超时失败 此时就很容易请求堆积而消耗资源 可以在一段时间内不再向它分配流量 类似于熔断
  • 故障恢复(Failback):指当服务调用出错了以后,将该次调用失败的信息存入一个消息队列中,然后由系统自动开始异步重试调用
    • 这种类型适合幂等调用的且没有返回值的链路主线服务调用
  • 并行调用(Forking):一开始就同时向多个服务副本发起调用,只要有其中任何一个返回成功,那调用便宣告成功
  • 广播调用(Broadcast):要求所有的请求全部都成功,这次调用才算是成功
容错策略 优点 缺点 应用场景
故障转移
系统自动处理,调用者对失败的信息不可见 增加调用时间,额外的资源开销 调用幂等服务
对调用时间不敏感的场景
快速失败 调用者有对失败的处理完全控制权
不依赖服务的幂等性
调用者必须正确处理失败逻辑,如果一味只是对外抛异常,容易引起雪崩 调用非幂等的服务
超时阈值较低的场景
安全失败 不影响主路逻辑 只适用于旁路调用 调用链中的旁路服务
沉默失败 控制错误不影响全局 出错的地方将在一段时间类不可用 频繁超时的服务
故障恢复 调用失败后自动重试,也不影响主路逻辑 推荐用于旁路服务调用,或者对实时性要求不高的主路逻辑
重试任务可能产生堆积,重试仍然可能失败
调用链中的旁路服务
对实时性要求不高的主路逻辑也可以使用
并行调用 尽可能在最短时间内获得最高的成功率 额外消耗机器资源,大部分调用可能都是无用功 资源充足且对失败容忍度低的场景
广播调用 支持同时对批量的服务提供者发起调用 资源消耗大,失败概率高 只适用于批量操作的场景

容错设计模式

断路器模式

通过代理(断路器对象)来一对一地(一个远程服务对应一个断路器对象)地接管服务调用者的远程请求。断路器会持续监控并统计服务返回的成功、失败、超时、拒绝等各种结果,当出现故障(失败、超时、拒绝)的次数达到断路器的阈值时,它状态就自动变为“OPEN”,后续此断路器代理的远程访问都将直接返回调用失败,而不会发出真正的远程服务请求

2020112014392

现实中,当以下两个条件同时满足 断路器就会打开:

  1. 一段时间内请求达到某个阈值
  2. 一段时间内请求的故障率达到某个阈值

舱壁隔离模式

无论是使用线程池或者信号量来隔离 本质上都是为了将故障隔离到最小的粒度 防止扩散

重试模式

重试时 应该同时满足以下几个条件:

  • 仅对链路主线的关键服务进行同步重试
  • 进队瞬时故障进行重试 像类似403 404这种错误重试没有意义
  • 仅对幂等调用进行重试
  • 重试要有终止条件
    • 重试次数
    • 超时终止

results matching " "

No results matching " "

results matching " "

No results matching " "