分布式系统中的重试机制
在分布式系统中,多个组件之间的网络通信随时可能发生故障。
客户端应用程序通过实现重试来处理这些失败。
常用的重试机制是在服务端程序抛出异常或超时时,客户端进行重试。重试次数可以由客户端或服务端指定,一般而言未指定重试间隔,或指定了固定时间间隔。
上述简单的重试机制在大多数场景下都可以正常工作,比如分布式系统中,服务端节点挂掉一个或少数几个,这时重试到其他节点,得到正常相应。客户端程序的服务质量可以不受影响。
而弊端在于:如果下游服务质量特别差,每次都有大量服务节点失效,此时的重试无疑加重了下游服务的压力,造成一定程度的雪崩效应。
指数回退 是处理失败网络调用重试的常用策略。简单地说,客户端在连续重试之间等待的时间间隔越来越长:
1 | wait_interval = base * multiplier^n |
指数回退在分布式系统中的一个主要缺点是,在同一时间开始回退的请求,也会在同一时间进行重试。这导致了请求簇的出现。那么,我们并没有减少每一轮进行竞争的客户端数量,而是引入了没有客户端竞争的时期。固定的指数退避并不能减少很多竞争,并会生成负载峰值。
抖动 就是为了减少请求簇而出现的,在重试的间隔中添加随机性,从而分摊了负载,避免了出现网络请求簇。
重试中的几个点
- 重试用来解决瞬时性故障,例如网络拥塞,数据库过载,是一种在有足够的冷却周期之后也许能自己恢复的故障。
- 重试前添加延迟,以解决初始化连接或网络包阻塞造成的故障
- 如果采用指数回退,记得添加最多重试次数
- 一定一定考虑可重试调用是否幂等