2023-03-29 更新:标题所反映的问题已经修复,现在:1、往队列发送了延迟消息后,消费者连接过一次后(包括连接后断开),DelayMsgNum 就能正确显示,而不是始终显示为 0,也不会被统计进 ActiveMsgNum;2、从队列中取出一条消息但一直不消费,即一直不删除,如果消息隐藏时间比较长,假设为 5min,那大概延迟 2min 后(不是官方说的 30s-60s),InactiveMsgNum 会正确显示,而不是一直显示为 0,同时 ActiveMsgNu 会相应减少。
以下是本笔记的原文。
使用 tencentcloud-sdk-nodejs-tdmq 的 DescribeCmqQueueDetail
接口查询一个 CMQ 队列的详情,会返回 ActiveMsgNum、InactiveMsgNum、DelayMsgNum 等数据,根据文档,这三个数据的意思分别是:
- ActiveMsgNum:在队列中处于 Active 状态(不处于被消费状态)的消息总数,为近似值。注意:此字段可能返回 null,表示取不到有效值。
- InactiveMsgNum:在队列中处于 Inactive 状态(正处于被消费状态)的消息总数,为近似值。 注意:此字段可能返回 null,表示取不到有效值。
- DelayMsgNum:延迟消息数。 注意:此字段可能返回 null,表示取不到有效值。
在 CMQ 后台也有对可见消息、不可见消息、堆积消息的解释:
- 可见消息:普通消息(非延时消息)被发送到普通消息队列时, 初始状态为可见。被取走后且超过隐藏时长时间后消息还未被删除,消息会重新变成可见状态。此处显示的数据刷新会有 30s 到 60s 延迟。
- 不可见消息:不可见消息过多一般是客户端未及时 ACK 导致的,产生不可见消息会消耗一定的内存,因此为每个队列设置了一定的容量上限。
- 堆积消息:消息堆积一般是生产速率大于消费速率或者消费出现阻塞导致的,产生堆积会消耗一定的磁盘存储,因此为每个队列设置了一定的容量上限。
综合以上两处说明,以下是我的理解:
- ActiveMsgNum:可以立即被消费的消息,不包括延迟消息,也不包括正在被消费的消息;
- InactiveMsgNum:仅指正在被消费的消息,所谓正在被消费,是指取出了,并且还没被删除,并且还没超过消息隐藏时长的消息,所以它不包括延迟消息;
- DelayMsgNum:仅指被延迟的消息,不包括可见消息,也不包括不可见消息;
但实际表现却和理论不一样,使用 DescribeCmqQueueDetail
接口查询一个队列的详情,给出来的数据和实际可能有较大误差,具体体现在:
- 从队列中取出消息但一直不删除,ActiveMsgNum 应该减少,InactiveMsgNum 应该增加,但实际情况是它们都保持不变,虽然文档说 ActiveMsgNum 可能会延迟 30-60s 才更新,但我等了将近 10 分钟了还不更新。这就导致了 ActiveMsgNum 虽然大于 0,但从队列中查询消息可能会返回
'(10200)no message'
。
- 往队列中发布 n 条延迟消息,但 n 总是被算入 ActiveMsgNum,而不是算入 DelayMsgNum,只有当消费者把队列中所有真正的可见消息全部消费完毕,接着再获取消息,这时,CMQ 才会意识到剩下的消息属于延迟消息,于是才会更新 DelayMsgNum 的数量。
总结一下:
- ActiveMsgNum:经常大于实际值,因为它可能包括了 InactiveMsgNum 和 DelayMsgNum,虽然文档说都不包括;
- InactiveMsgNum:我把 VisibilityTimeout 设置为 10 分钟,取出 n 条消息后 10 分钟内不删除,InactiveMsgNum 却一直保持为零,而不是 n;
- DelayMsgNum:延迟消息的计数默认被计入 ActiveMsgNum,只有当真正的可见消息都被消费完毕,延迟消息计数才会从 ActiveMsgNum 转移到 DelayMsgNum;
BTW,tencentcloud-sdk-nodejs-tdmq 还有一个 DescribeCmqQueues
接口,它可查询全量队列的信息,但它返回的可见消息数、延迟消息数比 DescribeCmqQueueDetail
更不准确,DelayMsgNum
永远是 null。
补充
咨询了腾讯云客服:
- DelayMsgNum:如果无消费者在线,则延时消息总数会统计为 0,当消费者连接过后(包括连接后断开),延迟消息计数才会显示正确,但事实上也不是,连接过后还是不会显示真实数据,只有当真实的可见消息都消费完毕后,延迟消息数才会从 ActiveMsgNum 计入 DelayMsgNum;
- InactiveMsgNum:CMQ 后台监控数据显示正确,但
DescribeCmqQueueDetail
给出的数据始终为 0,这是 bug,后续会修复,这个 bug 据我观察至少在 2022/11 上旬就出现了。
相关文章: