JAVA的重试机制

简介: java之重试机制

1. 什么是重试机制

重试模式,可以拆成重试+模式。

重试: 在工作流执行过程中,当执行到一个活动实例出现异常时,可以重新执行这个活动实例,直到成功,或者规定重试次数的最大值,当重试次数达到最大值时失败。

模式: 事物的标准样式,理论和实践之间的中介环节,具有一般性、简单性、重复性、结构性、稳定性、可操作性的特征。

重试模式: 透明地重试某些涉及与外部资源通信的失败的操作,尤其是通过网络,从而将调用代码与重试实现细节隔离开来的一种标准的解决方案。

2.为什么要用重试模式

为了解决什么样的问题?

客户端A连接到服务B的时候,服务B突发临时故障,并且该故障在短时间后将会恢复了正常。那么此刻客户端A要怎么做?

重试模式可以透明的有限的重试请求,提高客户端的请求的成功率和稳定性。

不用重试模式会怎么样?

如果失败不重试,那么此次操作就会返回失败,只能等待下次客户端重新发起请求。相对于有失败重试的机制的方案稳定性略差一些。

3.怎么用重试模式

什么场景适用

错误预计只会短时存在,并且通过后续尝试重复执行之前失败的请求可能会成功。

  • 组件和服务瞬间断开网络连接
  • 服务暂时不可用
  • 当服务繁忙时出现超时

什么场景不适用

  • 当错误可能会持续很长时间,因为此模式可能会影响应用程序的响应能力,
  • 不是由于短暂性错误而导致的故障,重新执行的情况下也不可能成功,例如业务异常:登陆的时候用户名密码错误,不能重试

重试模式在Java开源项目的使用

  • RocketMQ 消息发送重试

    rocketmq发送消息重试demo

rocketmq-producer-retrydemo.png
rocketmq-producer-retry-send.png

  • RocketQq 消息消费重试策略:

    消息重发延时级别为: 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

    如果消费失败,那么1S后再次消费,如果失败,那么5S后,再次消费,……直至2H后如果消费还失败,那么该条消息就会终止发送给消费者了!

    在实际中也许我们并不需要这么多重试,比如重试3次,可以通过message.getResumeTimes来判断重试次数,超过一定次数可以把消息存储起来并采用另一种方式处理。

使用不当有什么后果

  • 大量客户端过多的重试请求而导致某个服务持续过载,甚至耗尽服务的资源

如何正确使用重试模式

流程图

retry-flow.png

  • 关键步骤

    • 如何判断是否临时故障

      • 拦截故障,根据故障相关属性区分是否是临时故障还是永久故障,或者是无需重试的业务本身的异常
    • 是否是关键业务必须重试

      • 因为对于某些非关键操作,最好是快速失败而不是重试多次反而影响应用程序的吞吐量
    • 判断操作是否是幂等的

      • 例如,某个服务已经收到并成功处理该请求,但无法发送响应。此时如果重试操作不是幂等将会导致意外的副作用。
    • 最大重试次数设置多少
    • 是延迟重试还是立即重试
    • 如果延迟重试,重试尝试之间的间隔时间设置多少

      • 在尝试之间采用递增方式或指数方式增大延迟时间的方式
  • 其他

    • 目标服务如果已经处于繁忙的状态,避免采用延迟时间间隔最小的,且尝试次数较多的积极重试策略,这会进一步降低目标服务的性能

      • 如何判断服务出于繁忙的状态?
    • 如果某个请求在进行大量的重试后仍然失败,则此刻考虑使用断路器模式
    • 请确保针对各种故障状况充分测试重试代码,重试不能严重影响应用程序的性能或可靠性、不能导致服务和资源过载,不能导致争用状况或瓶颈
    • 只有充分了解失败操作的完整上下文后才能实现重试逻辑
    • 记录并调查服务或者资源可能的错误

      • 记录导致重试的所有连接故障,以便可以查明应用程序、服务或资源的底层问题。
      • 提前调查服务或资源最有可能发生的错误,针对该错误制定相应的应对策略,是重试还是快速失败

有没有用来实现重试模式的开源框架

4. 延伸思考

有没有功能类似的模式?

有没有功能相反的模式?

5.参考资料

微软Azure文档之Retry模式

Retry-pattern-examples-recommendations

Spring Retry的使用和原理

相关文章
|
缓存 Java API
Java工具篇之Guava-retry重试组件
Guava 是一组来自 Google 的核心 Java 库,其中包括新的集合类型(例如 multimap 和 multiset)、不可变集合、图形库以及用于并发、I/O、散列、缓存、原语、字符串等的实用程序!它广泛用于 Google 内部的大多数 Java 项目,也被许多其他公司广泛使用。 API 非常的简单,我们可以非常轻松的使用,来封装成我们业务中自己的组件。
872 0
|
2月前
|
设计模式 Java 应用服务中间件
Java面向容错编程之重试机制
容错编程是一种重要的编程思想,它能够提高应用程序的可靠性和稳定性,同时提高代码的健壮性。本文总结了一些作者在面对服务失败时如何进行优雅重试,比如aop、cglib等同时对重试工具\组件的源码和注意事项进行总结分析。
|
Java
Java:SpringBoot 整合Spring-Retry实现错误重试
Java:SpringBoot 整合Spring-Retry实现错误重试
137 0
|
设计模式 存储 运维
Java之Retry重试机制详解
Java之Retry重试机制详解
Java之Retry重试机制详解
|
Java API Spring
Java工具篇之Spring-retry重试组件
前面我们了解到了,Guava的重试组件,我们可以基于Guava的能力,来封装我们需要的能力来满足我们的业务。今天来分享Spring-Retry重试组件。当然Spring只是帮我们封装好了,如果你不想自定义 重试组件,那么我们可以直接使用Spring的能力来实现。 API 也是非常的简单,几个注解就可以搞定。
673 0
|
NoSQL Java Scala
Scala/Java - Redis 连接检测与重试
项目实现中需要连接 redis,为了防止因网络抖动或其他原因造成的客户端连接失败,一般需要增加重试机制判断 client 是否连接成功,之前写了一版重连代码发现有 bug,借此机会看下代码 bug 以及如何更好的重连 redis。...
336 0
Scala/Java - Redis 连接检测与重试
|
消息中间件 XML Java
Java函数调用重试的正确姿势
Java函数调用重试的正确姿势
185 0
突破Java面试(37)-基于Dubbo的服务治理、服务降级以及重试
如何基于dubbo进行服务治理、服务降级、失败重试以及超时重试?
3600 0
|
4天前
|
Java 调度
Java线程的六种状态
Java线程有六种状态: 初始(NEW)、运行(RUNNABLE)、阻塞(BLOCKED)、等待(WAITING)、超时等待(TIMED_WAITING)、终止(TERMINATED)。
13 1