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

SpringBoot方法超时抛出异常实现方案咨询(含Redis交互场景)

SpringBoot方法执行时长追踪与超时异常抛出方案

需求梳理

  • 监控Redis交互方法getValue的执行时间
  • 当执行时长超过指定阈值时,无论方法执行是否成功都抛出异常
  • 无需手动在业务代码中捕获结束时间,实现自动化的时长监控

实现方案:基于Spring AOP的无侵入式监控

用AOP切面织入时长监控逻辑,完全不修改原有业务方法的核心代码,同时满足超时即抛异常的要求。

1. 自定义超时监控注解

定义一个注解,用来标记需要监控的方法,并支持自定义超时阈值:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeoutMonitor {
    // 超时阈值,单位:毫秒,默认1000ms
    long threshold() default 1000;
}

2. 编写AOP切面类

通过环绕切面在方法执行前后记录时间,无论方法是否抛出异常(即使业务代码捕获了异常),都会在finally块中计算执行时长并判断是否超时:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TimeoutMonitorAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger(TimeoutMonitorAspect.class);

    @Around("@annotation(timeoutMonitor)")
    public Object monitorExecutionTime(ProceedingJoinPoint joinPoint, TimeoutMonitor timeoutMonitor) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object methodResult;
        
        try {
            // 执行原方法
            methodResult = joinPoint.proceed();
        } finally {
            // 计算执行时长,无论方法是否成功执行都会走到这里
            long executionDuration = System.currentTimeMillis() - startTime;
            long threshold = timeoutMonitor.threshold();
            
            if (executionDuration > threshold) {
                String methodSignature = joinPoint.getSignature().toShortString();
                String errorMsg = String.format("Method %s executed for %d ms, exceeds threshold of %d ms",
                        methodSignature, executionDuration, threshold);
                LOGGER.error(errorMsg);
                // 抛出自定义超时异常,上层可按需处理
                throw new MethodTimeoutException(errorMsg);
            }
        }
        
        return methodResult;
    }
}

3. 自定义超时异常类

创建专属的RuntimeException,方便上层调用方识别和处理超时场景:

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

4. 改造原有业务方法

只需在目标方法上添加自定义注解,设置对应的超时阈值即可:

import org.springframework.stereotype.Component;

@Component
public class CacheService {
    private static final Logger LOGGER = LoggerFactory.getLogger(CacheService.class);
    private final String className = CacheService.class.getSimpleName();
    private final RedisJedisTemplate redisJedisTemplate;

    // 构造注入Redis模板
    public CacheService(RedisJedisTemplate redisJedisTemplate) {
        this.redisJedisTemplate = redisJedisTemplate;
    }

    // 设置超时阈值为500毫秒,可根据业务调整
    @TimeoutMonitor(threshold = 500)
    public CacheResponse getValue(String key) {
        try {
            return redisJedisTemplate.opsForValue().get(key);
        } catch (Exception e) {
            LOGGER.error("{}: Error fetching data with key {} {}", className, key, e.getMessage());
            return null;
        }
    }
}

方案优势

  • 完全无侵入:业务代码无需修改时长监控逻辑,仅需添加注解
  • 覆盖所有场景:无论方法执行成功还是捕获了异常,都会触发超时判断
  • 灵活性高:每个方法可独立设置超时阈值,适配不同业务场景

内容的提问来源于stack exchange,提问作者Monish Das

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 09:35:13