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

Quarkus REST Client与@ClientExceptionMapper的错误处理问询

Kafka Sink HTTP连接器:按HTTP状态码控制重试与DLQ流程

针对你的需求,核心问题是要让重试机制识别并跳过40x类错误的重试,直接触发DLQ。你之前的ClientExceptionMapper返回null的方式无法阻止重试,因为框架会把这种情况视为未抛出可触发终止的异常,依然会执行重试逻辑。下面是可行的解决方案:

步骤1:定义不可重试的自定义异常

创建一个专属异常类,用来标记不需要重试的40x错误:

public class NonRetryableClientErrorException extends RuntimeException {
    public NonRetryableClientErrorException(String message) {
        super(message);
    }
}

步骤2:修改ClientExceptionMapper抛出异常

在自定义异常映射器中,遇到40x状态码时抛出上述异常,而不是返回null:

@ClientExceptionMapper
static RuntimeException toException(Response response) {
    switch (response.getStatusInfo().getFamily()) {
        case CLIENT_ERROR:
            String errorDetail = "40x客户端错误,将消息发送至DLQ: " + response.readEntity(String.class);
            CremHttpClient.log.error(errorDetail);
            // 抛出不可重试异常,告知框架终止重试
            return new NonRetryableClientErrorException(errorDetail);
        case SERVER_ERROR:
            // 50x错误抛出普通RuntimeException,触发重试
            return new RuntimeException("50x服务端错误: " + response.readEntity(String.class));
        default:
            return null;
    }
}

步骤3:配置@Retry注解排除不可重试异常

在你的消费者方法上,通过@Retry的exclude属性指定刚才定义的异常,让重试机制遇到该异常时直接跳过重试,进入DLQ流程:

@Retry(
    attempts = "3", // 自定义重试次数
    delay = "1000", // 自定义重试间隔
    exclude = NonRetryableClientErrorException.class
)
@DLQ(name = "your-dlq-topic-name") // 替换为你的死信队列主题名
public void consumeMessage(YourMessageType message) {
    // 调用HTTP接口的业务逻辑
}

原理说明

  • @Retry注解的exclude属性会过滤掉指定的异常,当该异常抛出时,重试机制不会触发,直接将消息路由到DLQ。
  • 通过自定义异常标记40x错误,能精准区分需要重试的50x错误和直接入DLQ的40x错误,避免无效重试。

内容的提问来源于stack exchange,提问作者Romain Wilbert

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 14:12:43