SpringBoot中使用Aop統一攔截MQ消息處理
SpringBoot中使用Aop統一攔截MQ消息處理
背景
在日常開發中,我們經常使用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、多業務。
這也是服務中間件接入時比較推薦的一種做法,特別適合用在日志鏈路追蹤、故障排查、消息埋點等場景,既統一又方便后期定位問題。

浙公網安備 33010602011771號