如何在Spring Retry的@Retryable方法中打印重试延迟序列
@Retryable 打印重试延迟序列实现方案
方案1:固定延迟场景(适配你当前的代码配置)
你当前使用的是固定延迟配置,直接将延迟值抽为常量即可直接引用打印,代码实现如下:
import org.springframework.retry.support.RetrySynchronizationManager; import lombok.extern.slf4j.Slf4j; import java.sql.SQLException; // 定义重试相关常量 private static final int MAX_RETRY_ATTEMPTS = 3; private static final long FIXED_RETRY_DELAY = 1000L; @Retryable( value = SQLException.class, maxAttempts = MAX_RETRY_ATTEMPTS, backoff = @Backoff(delay = FIXED_RETRY_DELAY)) void testMethod(String abc) throws SQLException{ // getRetryCount默认从0计数,+1对齐你期望的1/2/3编号规则 int retryNum = RetrySynchronizationManager.getContext().getRetryCount() + 1; log.info("Retry Number: {} delay : {}", retryNum, FIXED_RETRY_DELAY); }
运行后即可输出你预期的日志效果。
方案2:通用动态延迟场景(支持指数退避、随机退避等所有退避策略)
如果你后续使用动态退避策略(比如带乘数的指数退避),可以直接从重试上下文里获取实际生效的延迟值,不需要硬编码:
import org.springframework.retry.RetryContext; import org.springframework.retry.backoff.BackOffContext; import org.springframework.retry.backoff.ExponentialBackOffPolicy; import org.springframework.retry.backoff.FixedBackOffPolicy; import org.springframework.retry.support.RetrySynchronizationManager; import lombok.extern.slf4j.Slf4j; import java.sql.SQLException; @Retryable( value = SQLException.class, maxAttempts = 3, backoff = @Backoff(delay = 1000, multiplier = 2)) void testMethod(String abc) throws SQLException{ RetryContext context = RetrySynchronizationManager.getContext(); int retryNum = context.getRetryCount() + 1; long delay = 0L; // 从上下文获取退避对象,适配不同退避策略 BackOffContext backOffContext = (BackOffContext) context.getAttribute(ExponentialBackOffPolicy.BACK_OFF_CONTEXT); if (backOffContext instanceof ExponentialBackOffPolicy.ExponentialBackOffContext) { delay = ((ExponentialBackOffPolicy.ExponentialBackOffContext) backOffContext).getInterval(); } else if (backOffContext instanceof FixedBackOffPolicy.FixedBackOffContext) { delay = ((FixedBackOffPolicy.FixedBackOffContext) backOffContext).getBackOffPeriod(); } log.info("Retry Number: {} delay : {}", retryNum, delay); }
注意事项
- 如果你使用其他退避策略(比如均匀随机退避),只需要添加上对应
UniformRandomBackOffContext的类型判断分支,获取对应延迟字段即可。 - 如果你不需要重试次数从1开始计数,去掉
+1即可适配默认的0起始计数规则。
内容的提问来源于stack exchange,提问作者Velmurugan A
相关产品推荐
相关产品推荐

