You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 03:15:01