【发布时间】:2018-02-15 23:57:55
【问题描述】:
我正在使用带有 Java 和 Spring 框架的 RabbitMQ,并且我有一个生产者和一个消费者,它们都会运行多个实例,但是到达生产者的每个请求都会生成一条由消费者处理的消息,并且该消费者应该能够将答案回复给同一个生产者(与持有请求的生产者完全相同)。
所以要求是:
- 生产者将收到一个 HTTP 请求,然后生成一条消息并将其推送到队列中。
- 消息内容一次只能由一个消费者处理,其他消费者不得处理同一条消息。
- 该消息应等待确认。
- 任何消费者都可以处理消息,但是当消费者失败时,消息应该返回队列,因为我们需要能够从中恢复。
- 完成后,消费者应该回复与它现在持有请求完全相同的生产者。
- 如果生产者失败,该请求也应该失败,因此消费者应该检查生产者是否还活着,然后再回复它是否不可用,那么它应该失败。
所以:
请求-->生产者1-->队列-->消费者1
-->生产者1等待
--> consumer1 失败
--> 消息返回队列
--> consumer2 获取消息并从 1 停止的地方继续
--> consumer2 完成并确认请求消息并发送响应
--> consumer2 发现 producer1 失败了,所以需要发送失败信号
目前,我能想到的只有: 1.Direct Reply Pattern:但是这里的问题是消息有no ack要求,但是我需要能够从消费者失败中恢复 2. The RPC Model: 没有解决生产者失败的问题
还有其他解决方案吗?我做错了吗?
【问题讨论】:
-
你的最后一点与 rabbitmq 的使用逻辑有点不同。生产者不应该知道谁会收到消息,也不应该知道是否有人会。如果生产者知道有人会收到消息,那么为什么还要使用消息代理...只是要注意,任何发送消息的客户端都是生产者,而任何接收消息的客户端都是消费者。当然一个客户端可以同时是两个,即 RPC 示例。这也是为什么 rabbitmq 没有客户端故障处理(生产者或消费者)
-
@cantSleepNow 我们需要消息代理来进行恢复,如果我们使用直接调用,那么如果消费者失败了我们将无法恢复,我们也永远无法知道它正在处理哪些作业并且失败了。
-
我知道这是一个 Java 问题,但在 .NET 中有轻量级消息总线工具 MassTransit 和 NServiceBus 可以使用 RabbitMQ 作为消息代理来处理请求/响应。这两个工具位于 RabbitMQ 之上的抽象层,促进请求/响应、即发即弃和发布模式,并处理消息序列化/反序列化。我不知道是否有任何 Java 等价物。
标签: java spring rabbitmq amqp spring-cloud