消费者拿了消息没来得及确认就挂了,消息去哪里、多久回来、会不会无限重投?进程被杀和网络不通有什么差别?quorum 队列怎么限制重试?这篇把本系列前面几篇的零散结论补成完整的一套。
kill 之前 (ready, unacked) = (100, 100) kill -9 之后 381 ms,unacked 变回 0;(ready, unacked) = (200, 0)
操作系统关闭 TCP 连接,broker 立即发现,未确认消息很快(约 0.4 s)回到队列。
队列里剩 110 条:redelivered=True 的 60 条(m40~m99)、全新的 50 条(m100~m149);前 40 条(m0~m39)已确认,没有再出现 顺序: ['m40', 'm41', 'm42', 'm43', 'm44']……——被重新投递的回到了队首,原来的先后顺序保持不变
确认过的消息不会重投;未确认的回到队首并带 redelivered=True,顺序不变。
黑洞开始前 (ready, unacked) = (50, 50) 黑洞开始后 8.6 s,unacked 回到 0;(ready, unacked) = (100, 0)(heartbeat=3 s,约 3 倍超时,和第 22 篇的黑洞检测时间一致)
没有 TCP 关闭时只能靠心跳超时发现,约 3 倍超时(8.6 s),这段时间里未确认的消息被卡着。
每次拿到时 (redelivered, x-delivery-count 头): [(False, None), (True, 1L), (True, 2L), (True, 3L), '(队列里已没有这条消息)'] x-delivery-limit=3 的队列最终 (ready, unacked) = (0, 0)——超过次数之后消息被丢弃(这里没有配死信交换机)
quorum 队列在重投的消息上带 x-delivery-count,配合 x-delivery-limit 限制重试次数,超过后丢弃或进入死信。
经典队列 5 次 (redelivered, x-delivery-count): [(False, None), (True, None), (True, None), (True, None), (True, None)]
只有 redelivered 布尔值,没有计数;需要限制重试就在应用里数,或用死信重试环。