ActiveMQ查堆积、怎么追踪原因、常用命令+告警模板
下面把 ActiveMQ(Classic 5.x) 单独补全:先讲它的死信队列机制、怎么查堆积、怎么追踪原因、常用命令+告警模板,最后和 Rabbit/Rocket/Kafka 做一句对比。
一、ActiveMQ 死信队列(DLQ)基础
1. 默认行为
- 默认死信队列:
ActiveMQ.DLQ(共享 DLQ) - 重试次数:默认 maxRedeliveries=6,超过就进 DLQ
- 触发死信的场景:
- 消费者多次重试失败(>maxRedeliveries)
- 消息 TTL 过期
- 消息被消费者“毒信确认”(poison ACK)
- 事务回滚次数超限
2. 两种 DLQ 策略(生产必配)
在 activemq.xml 的 <destinationPolicy> 里配置:
(1)共享 DLQ(默认)
所有队列/topic 的死信都进 ActiveMQ.DLQ,不好排查。
<policyEntry queue=">">
<deadLetterStrategy>
<sharedDeadLetterStrategy/>
</deadLetterStrategy>
</policyEntry>
(2)独立 DLQ(推荐)
每个业务队列对应一个 DLQ,格式:
- Queue:
ActiveMQ.DLQ.Queue.原队列名 - Topic:
ActiveMQ.DLQ.Topic.原topic名
<policyEntry queue=">">
<deadLetterStrategy>
<individualDeadLetterStrategy queuePrefix="DLQ."/>
</deadLetterStrategy>
</policyEntry>
二、怎么检查 DLQ 有没有数据(3 种方法)
1. Web Console(最直观)
地址:http://MQ_IP:8161/admin
- 进入 Queues
- 找:
- 共享:
ActiveMQ.DLQ - 独立:
DLQ.xxx或ActiveMQ.DLQ.Queue.xxx
- 共享:
- 看 Number Of Pending Messages > 0 就是有死信堆积
2. 命令行(Linux)
(1)查看所有队列及消息数
# 进入 ActiveMQ 安装目录
cd /usr/local/activemq/bin
# 查看队列列表+消息数
./activemq-admin query -Q | grep -E "Name|Pending"
(2)过滤 DLQ 队列
./activemq-admin query -Q | grep -E "DLQ|ActiveMQ.DLQ"
3. JMX 查看(运维监控常用)
- MBean:
org.apache.activemq:type=Broker,brokerName=*,destinationType=Queue,destinationName=ActiveMQ.DLQ - 指标:
QueueSize(堆积数)
三、怎么追踪死信原因(关键属性)
1. 死信消息自带原因字段
消息属性里会有:
dlqDeliveryFailureCause:失败原因字符串(最关键)redeliveryCounter:重试次数originalDestination:原队列/topicexpiration:过期时间(如果是TTL死信)
常见 cause 内容:
Java.lang.Exception: 业务异常→ 消费者代码抛异常Message expired→ TTL 过期Redelivery limit exceeded→ 重试次数超限
2. Web Console 查看详情
- 进入 DLQ 队列 → Browse
- 点一条消息 → 看 Message Properties:
- 重点复制
dlqDeliveryFailureCause和originalDestination
- 重点复制
- 看 Body:消息体内容(JSON/文本)
3. 代码端查看(Java 示例)
while (true) {
Message msg = consumer.receive();
if (msg instanceof TextMessage) {
TextMessage tm = (TextMessage) msg;
// 死信原因
String cause = tm.getStringProperty("dlqDeliveryFailureCause");
// 原队列
String origDest = tm.getStringProperty("originalDestination");
// 重试次数
int retry = tm.getIntProperty("redeliveryCounter");
System.out.println("死信原因:" + cause);
}
}
四、消息重放(修复后重新入队)
1. Web Console 一键移动(推荐)
- DLQ 队列 → Browse → 勾选消息
- 点 Move → 选择 Original Destination(原队列)→ 确认
2. 命令行重放
# 把 ActiveMQ.DLQ 的消息移到 ORDER.QUEUE
./activemq-admin move -b tcp://localhost:61616 \
-q ActiveMQ.DLQ -d ORDER.QUEUE
五、告警配置模板
1. 监控指标
- 指标:
QueueSize(DLQ 队列待处理消息数) - 阈值:>0 即告警
2. 简易巡检脚本(crontab 1分钟)
#!/bin/bash
# activemq_dlq_check.sh
MQ_IP=127.0.0.1
DLQ_NAME=ActiveMQ.DLQ
# 获取 DLQ 消息数
COUNT=$(./activemq-admin query -Q -d $DLQ_NAME | grep Pending | awk '{print $NF}')
if [ $COUNT -gt 0 ];then
echo "ActiveMQ 死信队列 $DLQ_NAME 堆积 $COUNT 条!"
# 调用钉钉/企业微信告警接口
fi
3. Prometheus + Grafana 告警规则
groups:
- name: activemq_dlq
rules:
- alert: ActiveMQ_DLQ_Has_Messages
expr: activemq_queue_size{destination=~".*DLQ.*"} > 0
for: 10s
labels:
severity: error
annotations:
summary: "ActiveMQ 死信队列堆积"
description: "队列:{{$labels.destination}},数量:{{$value}}"
六、四大 MQ 死信机制一句话对比
- RabbitMQ:DLX+DLQ,靠
x-death头看原因,UI 友好 - RocketMQ:原生
%DLQ%+消费者组,消息轨迹最强,高并发首选 - Kafka:无原生DLQ,业务自定义dlq-topic,靠Header+日志追踪
- ActiveMQ:默认共享
ActiveMQ.DLQ,可配独立DLQ,原因在dlqDeliveryFailureCause
ActiveMQ 速查清单(配置+命令+脚本+告警)
一、核心配置(activemq.xml 直接复制)
1. 推荐配置:独立死信队列(生产环境)
每个业务队列生成专属 DLQ,便于排查
<!-- 目的地策略:全局队列生效 -->
<destinationPolicy>
<policyMap>
<policyEntries>
<!-- 匹配所有队列 -->
<policyEntry queue=">">
<!-- 死信策略:独立DLQ -->
<deadLetterStrategy>
<individualDeadLetterStrategy
queuePrefix="DLQ."
useQueueForQueueMessages="true"
useTopicForTopicMessages="false"/>
</deadLetterStrategy>
<!-- 最大重发次数:默认6次,可自定义 -->
<redeliveryPolicy>
<redeliveryPolicy maximumRedeliveries="6"/>
</redeliveryPolicy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
效果:原队列 ORDER_QUEUE → 死信队列 DLQ.ORDER_QUEUE
2. 默认配置:全局共享死信队列(不推荐排查)
所有消息失败统一进入 ActiveMQ.DLQ
<policyEntry queue=">">
<deadLetterStrategy>
<sharedDeadLetterStrategy/>
</deadLetterStrategy>
</policyEntry>
3. 消息过期自动进DLQ(TTL 配合)
如需消息超时进入死信,开启全局TTL策略:
<policyEntry queue=">">
<expirationMapCheckStyle>LAZY</expirationMapCheckStyle>
</policyEntry>
二、常用运维命令(进入 activemq/bin 目录执行)
基础环境
默认端口:
- Web控制台:
8161 - TCP连接端口:
61616
1. 启停服务
# 启动
./activemq start
# 停止
./activemq stop
# 重启
./activemq restart
# 查看状态
./activemq status
2. 查询队列/死信队列(核心排查)
# 查看所有队列 + 消息堆积数
./activemq-admin query -Q
# 只筛选所有 DLQ 死信队列
./activemq-admin query -Q | grep DLQ
# 查询指定单个死信队列详情
./activemq-admin query -Q -d DLQ.ORDER_QUEUE
3. 消息移动(死信重放,修复后使用)
# 将 DLQ 消息移动回原业务队列(通用格式)
./activemq-admin move \
-b tcp://127.0.0.1:61616 \
-q 死信队列名 \
-d 原业务队列名
# 示例:把 DLQ.ORDER_QUEUE 消息移回 ORDER_QUEUE
./activemq-admin move \
-b tcp://127.0.0.1:61616 \
-q DLQ.ORDER_QUEUE \
-d ORDER_QUEUE
4. 清空队列(谨慎!生产慎用)
# 清空指定队列所有消息
./activemq-admin purge -Q DLQ.ORDER_QUEUE
5. 查看连接、消费者
# 查看所有客户端连接
./activemq-admin connections
# 查看队列消费者
./activemq-admin consumers
三、Web 控制台操作(可视化排查)
访问地址:http://MQ_IP:8161/admin
默认账号密码:admin / admin
-
查看死信堆积
左侧 →Queues→ 找到DLQ.xxx/ActiveMQ.DLQ
查看字段:Number Of Pending Messages(待消费消息数) -
查看死信详情&原因
对应DLQ队列 → 点击Browse→ 选中消息dlqDeliveryFailureCause:失败根因(重点)redeliveryCounter:重试次数originalDestination:来源队列Message Body:原始消息内容
-
Web端重放消息
勾选消息 → 点击Move→ 选择原队列 → 提交
四、定时巡检脚本(Shell + Crontab)
脚本:activemq_dlq_check.sh
#!/bin/bash
# ActiveMQ 死信队列巡检脚本
MQ_BIN="/usr/local/activemq/bin"
# 替换为你的死信队列(多个用空格分隔)
DLQ_LIST="ActiveMQ.DLQ DLQ.ORDER_QUEUE DLQ.PAY_QUEUE"
MQ_URL="tcp://127.0.0.1:61616"
# 遍历所有死信队列
for dlq in $DLQ_LIST
do
# 获取堆积消息数
COUNT=$(${MQ_BIN}/activemq-admin query -Q -d ${dlq} 2>/dev/null | grep "Pending" | awk '{print $NF}')
# 判断是否有堆积
if [[ -n "$COUNT" && "$COUNT" -gt 0 ]]; then
MSG="【告警】ActiveMQ 死信队列 ${dlq} 存在堆积,消息数:${COUNT}"
echo ${MSG}
# ========== 对接钉钉/企业微信机器人(自行替换URL)==========
# curl -s "https://oapi.dingtalk.com/robot/send?access_token=XXX" \
# -H "Content-Type: application/json" \
# -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"${MSG}\"}}"
fi
done
添加定时任务(1分钟巡检一次)
# 赋予执行权限
chmod +x /usr/local/script/activemq_dlq_check.sh
# 编辑定时任务
crontab -e
# 写入规则
*/1 * * * * /usr/local/script/activemq_dlq_check.sh >> /usr/local/script/activemq_dlq_log.log 2>&1
五、Prometheus + Grafana 告警规则
依赖:activemq-exporter 采集监控指标
groups:
- name: activemq_dlq_alerts
rules:
# 死信队列出现消息立即告警
- alert: ActiveMQ_DLQ_Msg_Exists
expr: activemq_queue_size{destination=~"DLQ.*|ActiveMQ.DLQ"} > 0
for: 10s
labels:
severity: error
service: activemq
annotations:
summary: "ActiveMQ 死信队列堆积告警"
description: "队列名称:{{ $labels.destination }},当前堆积消息数:{{ $value }}"
六、常见死信原因速查表
| 异常字段内容 | 问题原因 | 处理方案 |
|---|---|---|
| Redelivery limit exceeded | 重试次数达到上限 | 排查消费者代码/依赖服务 |
| Message expired | 消息TTL超时未消费 | 调大TTL、提升消费能力 |
| Java Exception/NullPoint | 消费者代码抛异常 | 查看应用日志修复Bug |
| Transaction rolled back | 事务多次回滚 | 检查数据库/事务逻辑 |
七、五大MQ死信机制极简汇总(背诵版)
- RabbitMQ:DLX交换机+DLQ队列,依靠
x-death识别原因 - RocketMQ:原生
%DLQ%+消费组,消息轨迹完善,高并发首选 - Kafka:无原生死信,业务自建DLQ Topic,靠Header+日志排查
- ActiveMQ:默认
ActiveMQ.DLQ,可配置独立DLQ,原因存dlqDeliveryFailureCause - 总结:业务系统优先 RocketMQ;传统老旧项目多见 ActiveMQ;大数据流用 Kafka;路由复杂选 RabbitMQ。

浙公网安备 33010602011771号