


























背景
在日常开发中,我们经常使用mq来实现异步处理等功能,这个过程就涉及到追踪日志链路以便于排查问题,这时候就可以用 Spring AOP 来优雅地解决这些问题。
项目中代码示例:
1 @Slf4j 2 @Aspect 3 @Component 4 public class RocketMqMdcAspect { 5 6 @Pointcut("execution(* org.apache.rocketmq.spring.core.RocketMQListener+.onMessage(..))") 7 public void rocketMQListenerMethods() {} 8 9 @Around("rocketMQListenerMethods()") 10 public Object aroundOnMessage(ProceedingJoinPoint joinPoint) throws Throwable { 11 // 获取消息体 12 Object arg = joinPoint.getArgs()[0]; 13 String originMessage = arg != null ? arg.toString() : "null"; 14 15 // 长消息截断,避免日志过长 16 String message = originMessage.length() > 1000 17 ? "消息过长,展示前1000个字符," + originMessage.substring(0, 1000) 18 : originMessage; 19 20 try { 21 // 设置日志追踪 ID 22 String requestId = UUID.randomUUID().toString(); 23 MDC.put("requestId", "mq:" + requestId); 24 25 log.info("收到消息 ====> body:{}", message); 26 Object result = joinPoint.proceed(); // 执行目标方法 27 log.info("处理消息结束 ====> body:{}", message); 28 return result; 29 } catch (Exception e) { 30 log.error("处理消息异常 ====> body:{}", originMessage, e); 31 throw e; // 向上抛出异常 32 } finally { 33 MDC.clear(); // 清理上下文,避免内存泄漏 34 } 35 } 36 }
通过上面的代码示例,说明以下几个关键点:
1. 拦截表达式
@Pointcut("execution(* org.apache.rocketmq.spring.core.RocketMQListener+.onMessage(..))")
匹配所有实现了 RocketMQListener 接口的类中,名为 onMessage 的方法,无论参数是什么、返回值是什么。
2. 日志链路追踪
MDC.put("requestId", "mq:" + UUID.randomUUID());
利用 SLF4J 的 MDC 机制,把 requestId 注入到日志上下文;
配合 logback 配置中的 %X{requestId},实现链路追踪。
3. 异常处理封装
将所有异常集中处理,并做“非致命业务异常跳过”的容错逻辑。
4. 依赖和配置提示
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> </dependency>
logback配置片段 (logback-spring.xml)
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="false" debug="false"> //... <!-- 日志格式, 参考:https://logback.qos.ch/manual/layouts.html --> <property name="currentLoggerPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [requestId=%X{requestId}] [%logger{15}] [%method,%line] - %msg%n" /> </configuration>
总结
使用 Spring AOP 拦截 RocketMQ 消息消费逻辑,有以下几个好处:
1. 日志增强:让日志统一、结构化、可追踪;
2. 异常集中处理:便于容错和告警;
3. 消息无侵入:业务代码无感知,维护成本低;
4. 通用性强:拦截逻辑复用性高,适用于多 topic、多业务。
这也是服务中间件接入时比较推荐的一种做法,特别适合用在日志链路追踪、故障排查、消息埋点等场景,既统一又方便后期定位问题。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。