调用服务的重试策略

目录

1. 在什么情况下应该重试

2. 常见的重试实现方式

3. 开箱即用的重试工具


在调用第三方服务时或者微服务间调用时,重试策略是一种常见的开发模式,即当调用服务不符合预期时(错误、数据异常),进行多次重试,以期待在下一次重试时,获得期待的返回值。

1. 在什么情况下应该重试

我们需要考虑的因素包括

  • 错误类型:例如网络异常或者请求频次限制一般可以通过重试解决,而如果是请求数据参数缺失,返回 4xx 错误,此时就不应该重试
  • 调用服务的幂等性:要特别关注,你调用的服务重复处理相同参数的请求,会不会造成 bug,例如数据一致性的问题
  • 成本和资源消耗:例如下游服务本身非常耗费资源,就要谨慎考虑是否需要重试;另外还需要考虑网络成本
  • 用户体验:考虑重试对用户体验的影响,如是否会导致用户长时间等待或出现错误提示;这里的用户也可能是接口调用方,因为太多的重试耗费的时间,可能直接导致你的上游调用方超时

下面的表格例举了一些常见错误的重试策略

错误类型

接口幂等

是否应该重试

接口非幂等

是否应该重试

Connection Timeout

链接超时,这时目标服务还没有开始处理请求

Read Timeout

读超时,这时目标服务已经开始处理请求了

Circuit Breaker Tripped

微服务中的一种保护策略,目标服务并未收到请求

400: Bad Request

请求异常,例如请求方法不对,参数不全等,重试没有意义

401: Unauthorized

未授权,重试没有意义

404: Not Found

资源不存在,,重试没有意义

429: Too Many Request

请求过多,需要较长时间的重试间隔

否则会造成短时间的请求翻倍,增加问题严重性

是(长重试间隔)是(长重试间隔)

500: Internal Server Error

造成服务器内部错误的问题可能会有很多,有的通过重试可以解决,有的则不行,所以最好进行重试

503: Service Umavailable

这个错误一种常见的场景是网关层检测不到后端可用的服务时返回,通过重试,有望解决该问题

2. 常见的重试实现方式

一般有如下两种常见的重试方式

  • 程序流程内重试
    • 方案:在循环中,try catch 住请求代码,在判断需要进行重试时,sleep 一段时间
    • 优点
      • 实现简单
      • 实时请求和后台服务都可以尝试这种重试策略
    • 缺点
      • 可能会导致程序在重试期间占用过多资源,影响整体性能
      • 实现复杂的重试策略时,会造成重试逻辑和业务逻辑耦合在一起,增加维护成本
      • 可能在本来下游服务压力大的时候,造成请求成倍增长
  • 通过消息队列控制重试
    • 方案
      • 当发生意外情况时,将 上下文数据和重试次数 打包发送到某个队列系统或者类似功能的系统(数据库也可以担任这一角色)中,其中 上下文数据 用来恢复现场
      • 单独的定时任务或者队列消费者,异步进行重试操作。
    • 优点
      • 解耦重试逻辑与主业务逻辑,使主流程更加简洁清晰,在实现复杂的重试逻辑时尤为明显
      • 便于对重试操作进行集中管理和监控,方便统计重试次数、成功率等指标
      • 对于一些资源密集型或耗时较长的重试操作,可以在单独的线程或进程中进行,减少对主服务的影响
    • 缺点
      • 不适用于实时服务,更加适用于后台服务
      • 引入了额外的消息队列或类似系统,增加了系统的复杂性和维护成本

3. 开箱即用的重试工具

以下是 Java 和 Python 中一些常见的开箱即用或便捷实现重试的机制和第三方包(但这些工具都只简化了程序流程内重试这一方案):

  • Java:
    • Spring Retry:如果您使用 Spring 框架,可以使用 Spring Retry 模块来实现重试功能。
    • Guava:提供了 Retryer 类来实现简单的重试逻辑。
  • Python:
    • tenacity:这是一个强大且易于使用的 Python 重试库。
    • retrying:可以方便地设置重试策略,例如重试次数、间隔等。

参考文档:

Building Resilient Systems With Retry Patterns | HackerNoon

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值