在业务开发中,常常会遇到出现异常,对接其他系统的时候需要重试,而如何优雅的进行重试又是一个需要考虑的问题。目前在常用的框架中,可以看到Spring Retry作为一个轻量级的重试框架,我们可以基于此来实现自己的重试,为业务代码的健壮性和异常处理做一个更好的处理。
Spring Retry的使用方法: 1)引入Spring Retry的依赖,主要为Spring Retry和Spring Aop
2)在启动类中开启EnableRetry注解
3)在业务系统的业务方法中引入对应的注解,比如: @Retryable(value = orderException.class, maxAttempts = 3, backoff = @Backoff(delay = 500), recover = "orderExceptionRecover")
4)在recover方法中执行具体的异常处理 ,也即达到3次后,需要进行的处理 @Recover
我们引入了相关注解就能完成异常中的重试和处理。那为什么会可以达到这样的效果呢?下面我们从Spring Retry的执行流程来理解Spring Retry。
首先我们可以看到入口: RetryConfiguration实现了InitializingBean和SmartInitializingSingleton。因此我们可以看到: 进行retry配置的后置方法,获取对应的配置的注解信息。首先会找4个findBean的信息,进行填充,设置顺序order。
afterSingletonsInstantiated方法可以看到,查询带RetryListener的注解,如果不为空,则将其添加到AnnotationAwareRetryOperationsInterceptor中。
完成上面的注解信息填充后,就可以进行拦截方法的增强了。AnnotationAwareRetryOperationsInterceptor的invoke方法会对相关注解进行相关信息的获取。拿到拦截的方法,进行增强。
找到合适的RetryOperationsInterceptor,调用invoke方法,从而调用doExecute执行具体的重试方法。如果存在监听,则执行自定义的监听中的方法,比如成功doOnSuccessInterceptors或者自定义的相关方法,均采用自定义重写监听方法。注册异常信息到上下文。执行错误拦截器。查看是否需要进行延迟,backoff,如果存在,其本质是执行sleep操作从而达到延迟重试的目的。
在尝试最后一次重试后,依然出现出现异常,会执行重试回调recover方法,依然是调用AnnotationAwareRetryOperation从而拿到对应的recover方法,调用具体的方法进行拦截增强。
其本质是基于Spring的Aop实现拦截增强。从而达到自定义的注解解析和获取,然后执行拦截增强。