惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Simon Willison's Weblog
Simon Willison's Weblog
T
Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Spread Privacy
Spread Privacy
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Engineering at Meta
Engineering at Meta
T
Tenable Blog
C
Cisco Blogs
T
The Blog of Author Tim Ferriss
NISL@THU
NISL@THU
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
P
Privacy & Cybersecurity Law Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
S
Secure Thoughts
N
News and Events Feed by Topic
Google DeepMind News
Google DeepMind News
博客园 - 三生石上(FineUI控件)
Microsoft Azure Blog
Microsoft Azure Blog
月光博客
月光博客
H
Hacker News: Front Page
I
InfoQ
L
LangChain Blog
Security Latest
Security Latest
The Cloudflare Blog
Forbes - Security
Forbes - Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Stack Overflow Blog
Stack Overflow Blog
TaoSecurity Blog
TaoSecurity Blog
量子位
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
Visual Studio Blog
Scott Helme
Scott Helme
爱范儿
爱范儿
A
Arctic Wolf
F
Full Disclosure
酷 壳 – CoolShell
酷 壳 – CoolShell
Schneier on Security
Schneier on Security
N
News and Events Feed by Topic
C
CXSECURITY Database RSS Feed - CXSecurity.com
L
LINUX DO - 最新话题
V2EX - 技术
V2EX - 技术
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
The Hacker News
The Hacker News
Hugging Face - Blog
Hugging Face - Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
Know Your Adversary
Know Your Adversary
Application and Cybersecurity Blog
Application and Cybersecurity Blog

博客园 - 欢乐豆123

软件设计师考试 - 有限自动机 软件设计师考试 - 排序算法 哈夫曼树以及哈夫曼编码 软件设计师案例题型 - DFD(数据流图) 软件设计师考试 - 二分查找 软件设计师考试 - Gantt图与PERT图(项目管理) 软件设计师考试 - 数据表示(原码、反码、补码、移码) 软件设计师考试 - 上午题型分析 软件设计师考试 - 下午题型分析 软件设计师考试-应用技术 内存溢出问题 常见的算法类型 排序算法的介绍 微信生态梳理 海明码介绍 Elasticsearch 实战:基于 function_score 的搜索与权重排序 Nexus的简单介绍以及如何上传自定义包 设计模式-桥接模式(Bridge Pattern) 设计模式简介 jmeter压测 sdkman-管理多个版本的JDK 项目管理流程以及规范 Java-泛型的使用
SpringBoot中使用Aop统一拦截MQ消息处理
欢乐豆123 · 2025-05-21 · via 博客园 - 欢乐豆123

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、多业务。

    这也是服务中间件接入时比较推荐的一种做法,特别适合用在日志链路追踪、故障排查、消息埋点等场景,既统一又方便后期定位问题。