RabbitMQ是否需要单独的死信交换机?

6
我已经为我的队列设置了死信路由,以便将被拒绝的消息重新排队并延迟数秒,防止临时消费者错误堵塞队列。我已经设置了工作队列和死信队列都绑定到同一个交换机上:

Flow chart depicting my intended flow of messages. Description below.

外部生成的传入消息被路由到交换机,然后放置在工作队列中。在处理消息时,消费者可能会因为一些临时错误(比如爬虫从网站接收到500错误)而失败。
我们不会拒绝消息并将其重新放置在队列的头部(导致无限循环),而是将被拒绝的消息(使用requeue=0)路由到交换机,并将死信队列添加为路由键。在这里,每个消息都会接收到X秒的TTL,之后它将被拒绝,因此被路由回交换机,并将路由键设置为原始工作队列。

然而,在查看文献和在线示例时,似乎每个人都建议路由到单独的死信交换机:

Flow chart depicting the commonly used flow of messages. Description below.

外部生成的进入消息被路由到工作交换机,然后放置在工作队列中。如果消费者失败,则消息将被拒绝(使用requeue=0),并将被路由到死信交换机。死信交换机将消息路由到死信队列,消息的TTL将过期,再次被拒绝的消息将被路由回工作交换机。
第二个设计相对于第一个有哪些关键优势?我无法确定,但我对RabbitMQ也不是太自信。
1个回答

1
取决于您使用的交换类型以及需要执行的其他路由。如果您同时将原始消息和重新排队的消息发送到同一交换机,则需要区分以下内容:
  • 新消息可能会被路由到多个队列或根本不路由
  • 失败的消息应仅路由到延迟队列
  • 延迟的消息应仅路由到它们失败的单个队列中
我的此模式实现中,我使用两个额外的交换机(均在按需动态声明)以使其尽可能独立于原始路由配置。
  • 消费者确认原始消息,并手动重新发布到“开始”交换机。这样可以提供一些额外的灵活性,例如在消息上设置自定义标头,并将具有不同TTL的多个延迟队列附加到同一个工作队列上。
  • “开始”交换机是一个扇形交换机,绑定到特定的“等待”队列,如您第二张图所示。
  • 当“等待”队列中的消息TTL过期时,它会路由到单独的“完成”交换机,设置为死信交换机。
  • 该交换机也是一个扇形交换机,仅绑定到原始工作队列。这确保不会创建其他副本的消息到已成功处理它的其他队列。
  • 因此,消息以其原始路由键返回到原始队列。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接