java - 跨 RabbitMQ 队列的消息弹性最佳实践

标签 java rabbitmq

我正在尝试了解 RabbitMQ 的最佳用途以满足以下问题。

作为上下文,我不关心这个用例中的性能(我的这个流的峰值 TPS 是 2 TPS),但我关心弹性。

我在集群中安装了 RabbitMQ 并忽略死信队列,基本流程是我有一个服务接收请求,创建一个持久消息,它在一个事务中排队到一个持久队列(此时我是很高兴请求被保护到磁盘)。然后我有另一个进程监听消息,它读取(不使用自动确认),做一堆事情,将新消息写入事务中的不同交换队列(现在再次高兴这个消息被保护到磁盘)。假设交易成功完成,它会手动将消息返回给原始消费者。

在这一点上,我唯一的失败场景是我在提交事务以写入我的第二个队列和返回 ack 之间出现故障。这将导致一条消息可能被处理两次。我还能做些什么来弥补这个差距,还是我必须想出一种方法来处理重复的消息。

作为上下文的最后一点,服务是用 java 编写的,因此使用 java 客户端库。

保罗菲茨。

最佳答案

首先,我建议你看看这个指南here其中有很多关于您的主题的有效信息。

来自 RabbitMQ 指南:

在生产者处

When using confirms, producers recovering from a channel or connection failure should retransmit any messages for which an acknowledgement has not been received from the broker. There is a possibility of message duplication here, because the broker might have sent a confirmation that never reached the producer (due to network failures, etc). Therefore consumer applications will need to perform deduplication or handle incoming messages in an idempotent manner.

在消费者处

In the event of network failure (or a node crashing), messages can be duplicated, and consumers must be prepared to handle them. If possible, the simplest way to handle this is to ensure that your consumers handle messages in an idempotent way rather than explicitly deal with deduplication.

所以,关键是根本不可能以任何方式保证您的这种“失败”场景不会发生。您将始终不得不处理网络故障、磁盘故障、在这里放置一些东西故障等。

您在这里要做的是依靠消息传递架构并在可能的情况下实现消息的“幂等性”(这意味着即使您处理消息两次也不会发生任何事情错了,检查 this )。 如果不能,则应提供某种“已处理消息”列表(例如,您可以在每条消息中使用 guid)并在每次收到消息时检查此列表;在这种情况下,您可以简单地丢弃它们。

更“理论”一点,this来自 Brave New Geek 的帖子非常有趣:

Within the context of a distributed system, you cannot have exactly-once message delivery.

希望对您有所帮助:)

关于java - 跨 RabbitMQ 队列的消息弹性最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36894690/

相关文章:

java - 需要 Spring Kafka KafkaTemplate.flush() 吗?

django - 无法连接到 amqp ://guest:**@127. 0.0.1:5672//: [Errno 111] 连接被拒绝

php - rabbitmq 在 linux 中发送数据 php

docker - 如何在Docker Cloud上设置RabbitMQ集群?

java - 将用户字符串输入到循环数组中

java - Swagger POST 返回 403 Forbidden Spring boot Spring security

java - java中分隔字母和数字的正则表达式

java - 创建 jar 文件

ruby-on-rails-3 - 如何在 Rails 和 Thin 中启动兔子线程

rabbitmq - Celery RabbitMQ 代理故障转移连接问题