Quarkus中@Retry注解使用报错:线程阻塞问题排查与解决
Quarkus 3.8.5中@Retry结合@Blocking方法触发线程阻塞错误的原因与解决方案
错误原因
你配置的@Retry注解中,delay=1且delayUnit=HOURS,意味着每次重试间隔会让当前Worker线程休眠整整1小时。而Quarkus开发模式下,Vert.x Worker线程的默认最长阻塞时间限制是60秒(60000ms)。当Retry逻辑调用Thread.sleep()让线程休眠时,休眠时间远超阈值,触发了Vert.x的线程阻塞检测机制,抛出Thread blocked异常。
解决方案
方案1:缩短Retry延迟时间
如果业务允许,将Retry的间隔调整为小于60秒的值,避免单次阻塞超过阈值:
import java.util.concurrent.TimeUnit; import io.smallrye.faulttolerance.api.Retry; import io.quarkus.vertx.Blocking; @Retry(jitter = 0, delay = 30, delayUnit = TimeUnit.SECONDS, maxDuration = 4, durationUnit = TimeUnit.HOURS) @Blocking public void myMethod(final String value) { // blocking code }
方案2:调整Worker线程阻塞超时阈值
在application.properties中修改Vert.x Worker线程的最长执行时间限制,匹配你的Retry延迟时长:
# 设置为1小时(3600000毫秒),对应Retry的delay配置 quarkus.vertx.max-worker-execution-time=3600000
注意:开发模式下的线程阻塞检测是为了及时发现不合理的长阻塞操作,调整阈值仅适合确有必要的场景,生产环境可根据实际需求配置。
方案3:改用异步重试逻辑(可选)
将方法改为异步返回类型,让Retry使用非阻塞的延迟方式(依赖SmallRye Fault Tolerance的异步支持),避免占用Worker线程休眠:
import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import io.smallrye.faulttolerance.api.Retry; @Retry(jitter = 0, delay = 1, delayUnit = TimeUnit.HOURS, maxDuration = 4, durationUnit = TimeUnit.HOURS) public CompletableFuture<Void> myMethod(final String value) { return CompletableFuture.runAsync(() -> { // blocking code }, Executors.newFixedThreadPool(1)); }
内容的提问来源于stack exchange,提问作者lecogiteur
相关产品推荐
相关产品推荐

