死信队列¶
https://blueprints.launchpad.net/zaqar/+spec/dead-letter-queue
问题描述¶
目前,如果消息被多次声明但仍然无法成功处理,Zaqar 无法采取任何措施。如果 Zaqar 可以提供死信队列支持,让用户为队列 B 提供一个现有的队列 A 作为死信队列,那将会很好。死信队列存储这些消息,允许开发者查找常见模式和潜在的软件问题。
提议的变更¶
1. 在队列的元数据中添加三个新的保留属性:_max_claim_count 和 _dead_letter_queue。
_max_claim_count 是消息可以被声明的最大次数。通常,这意味着消息无法成功处理。此属性没有默认值。如果未设置,则表示当前队列未启用此功能。
_dead_letter_queue 是消息在达到最大声明次数后将被移动到的目标。不支持将队列 C 作为队列 B 的死信队列,而队列 B 又被设置为队列 A 的死信队列。这不是本规范要解决的问题。从技术上讲,即使用户可以将队列 C 设置为队列 B 的死信队列(当队列 B 是队列 A 的死信队列时),由于移动是由声明触发的,因此如果用户不显式声明队列 B 中的消息,则不会发生任何事情。
_dead_letter_queue_messages_ttl 是将消息移动到 DLQ 后的新 TTL 设置。如果未设置,则保留当前的 TTL。
2. 为了获得更好的性能,在进行验证时,确保 DLQ 和当前队列位于同一个池中。
3. 在数据库中的消息中添加一个新字段,用于保存声明计数。
声明创建的变更
4.1. 从消息中获取当前的声明计数,并通过加一更新声明计数。
4.2. 检查声明计数是否超过队列元数据中定义的最大声明计数。如果未超过
_max_claim_count,则执行正常的声明。4.3. 如果声明计数超过
_max_claim_count,则直接将消息移动到死信队列。考虑到 DLQ 的目标,我们希望保留消息的声明信息。因此,取决于存储后端,"移动"可能会引入限制。例如,对于 MongoDB 后端,我们可能需要通过直接更改队列名称将消息从源队列移动到 DLQ。这意味着两者必须在同一个存储池中创建。移动消息后,Zaqar 将不会对死信队列中的这些消息采取任何操作。用户可以使用/将使用这些消息来调试为什么这些消息无法成功处理。换句话说,允许开发者从这些消息中查找常见模式和潜在的软件问题。
4.4. 移动到 DLQ 的消息将根据设置
_dead_letter_queue_messages_ttl更新它们的 TTL。如果未设置,则保留消息的当前 TTL。
缺点¶
基于当前设计,由于技术权衡,我们可能存在一个限制。将消息从源队列移动到死信队列时,最好保留声明信息,但如果我们要这样做,则必须确保这两个队列位于同一个存储池中。不同后端上的实现可能不同。
备选方案¶
无
实现¶
负责人¶
- 主要负责人
flwang <flwang@catalyst.net.nz>
里程碑¶
- 完成目标里程碑
Pike-3
工作项¶
在队列元数据中添加 _max_claim_count 和 _dead_letter_queue 作为保留属性
添加对新保留属性的验证
添加一个新字段来计算消息的声明次数,这需要针对 maongoDB、swift 和 redis 进行。
添加声明创建中的变更,该变更将为消息添加声明计数,并检查计数是否超过队列元数据中定义的最大声明计数。如果超过,则将消息移动到死信队列。
添加此功能的发布说明
更新 API 参考
添加此功能的开发者文档
相应地更改单元测试、功能测试和 tempest 测试。
依赖项¶
无
注意
本作品采用知识共享署名 3.0 非移植许可协议授权。 http://creativecommons.org/licenses/by/3.0/legalcode