Spring Retryable - 异步上下文

3
在异步上下文中使用@Retryable时遇到了问题,我有一个服务调用返回了SocketTimeOut异常。我本来期望它重试3次,我确实使用了@EnableRetry,但是在日志中看到了一些奇怪的东西,即sleep interruptedException。以下是部分堆栈跟踪。
Caused by: java.lang.InterruptedException: sleep interrupted at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:118) ~[spring-retry-1.2.1.RELEASE.jar!/:na] at someservice.somemethod(someservice.java) ~[classes/:na] 2018-01-18 18:59:39.818 INFO 14 --- [lTaskExecutor-1] someExceptionHandler : Thread interrupted while sleeping; nested exception is java.lang.InterruptedException: sleep interrupted at org.springframework.retry.backoff.ThreadWaitSleeper.sleep(ThreadWaitSleeper.java:30) ~[spring-retry-1.2.1.RELEASE.jar!/:na] at org.springframework.retry.backoff.StatelessBackOffPolicy.backOff(StatelessBackOffPolicy.java:36) ~[spring-retry-1.2.1.RELEASE.jar!/:na] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_141] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) ~[spring-aop-4.3.8.RELEASE.jar!/:4.3.8.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) ~[spring-aop-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
不确定这是否与问题有关,但在读取超时后发生了这种情况,我原本期望它重试,但是在日志中看到了这个。我知道Spring retry默认等待1秒钟,我想知道它是否被中断,从而影响了它的重试能力。
谢谢!
1个回答

0
由于:java.lang.InterruptedException: sleep interrupted at
简单地意味着在您的应用程序中,当线程在backOff等待时,有其他东西中断了它,从而终止了重试场景。
这是设计上的考虑...
if (this.logger.isDebugEnabled()) {
    this.logger
            .debug("Abort retry because interrupted: count="
                    + context.getRetryCount());
}

当你中断一个线程时,你明确地告诉它停止正在做的事情(如果它正在进行可中断的操作,比如睡眠)。

谢谢回复,Gary。那么如果我们没有指定退避策略会发生什么呢?也就是说,我们的方法只是用@Retryable注解而没有任何选项,退避时间是零还是默认为1秒?我读到可能是零?所以我尝试添加了以下代码: Thread.currentThread.interrupt(),我看到它停止了重试,但是我得到了相同的错误,但是我中断的线程应该在运行而不是睡眠,然后我遇到了睡眠中断的问题。这是一个基本的SSL套接字连接超时问题,如果需要的话,我会尝试混淆一些代码并添加进来。 - aspiringCoder
1
你可以使用NoBackOffPolicy来避免休眠,但是无法使用@Retryable注解进行连接;你需要将拦截器作为@Bean进行连接,并在注解的interceptor属性上使用它。 - Gary Russell
所以只是确认默认情况下(没有选项的注释),线程会休眠?通过添加拦截器,并提供NoBackOffPolicy,它就不会休眠了吗? - aspiringCoder
标记为正确,这对我来说应该可以工作,因为SSL套接字调用的超时时间是15秒 - 实际上不需要睡眠。看看效果如何,谢谢你的信息! - aspiringCoder
真快的跟进 - 我们能不能就这样做 -{@Retryable(backoff = @Backoff(0))} - aspiringCoder
2
很遗憾,使用基于休眠的退避策略时,任何小于等于0的值都会被强制转为1毫秒。而且无论如何,“Thread.sleep()”都会被无条件调用,即使休眠时间为0,也会被中断。 - Gary Russell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接