【发布时间】:2020-06-23 00:19:19
【问题描述】:
ActiveMQ 是否支持幂等生产者?我知道 Camel 有一个幂等消费者模式来检测和处理重复消息,但我想知道这是否可以在源(生产者)处防止。
这里有一点背景。我有水平扩展的应用程序访问相同的数据库。有一个特定的表维护特定进程的状态。这些水平应用程序应该能够读取状态并调用另一个进程,但是只有其中一个应该能够调用它。一旦满足所需条件,此应用程序会定期轮询数据库并将消息发布到消息传递代理。但我希望其中一个负载平衡应用程序应该能够发布消息。
我认为的一种粗略方法是......
在机器 1 上:
- 读取数据库以检查是否满足必要条件。
- 在向代理发布消息之前,将记录写入另一个状态表,并使用唯一键标识进程和提交。如果此操作由于违反唯一键约束而失败,则意味着另一台机器上的进程成功发布了消息。
- 将消息发布到代理
- 如果消息发布失败,由于某种原因,根据唯一键/主键对状态表进行删除操作。
在机器 2、3、4 等上运行的相同应用程序可以执行相同的操作。
以下是我很快注意到这种方法的一个缺陷。
假设机器 1 能够完成第 2 步,但未能执行第 3 步并继续执行第 4 步。同时,当第 2 步失败时,机器 2 将继续前进,而不再尝试再次读取状态并发布消息.
为了解决这个问题,我需要在第 3 步重试,直到消息成功发布到代理。
另一种选择是使用https://camel.apache.org/components/latest/eips/idempotentConsumer-eip.html 模式。但这本质上是消费者方面的过滤器。虽然这将达到我的目的,但在消息发布方面是否有类似的现成方法可用。
我想知道,这种方法是否正确或任何更好的替代方法,或者任何现有的库可以用于在本地或远程跨 JVM 执行锁定机制。
【问题讨论】:
-
感谢您的建议。我还没有实施这个建议。 Artemis 不是一个选项,因为它尚未在我们的项目中获得批准。
-
不获批有什么具体原因吗?您使用的是哪个版本的 ActiveMQ?
-
我的回答是否解决了您的问题?如果是这样,请将其标记为正确,以帮助将来有同样问题的其他人。如果没有,请澄清缺少的内容。谢谢!
标签: java jms activemq idempotent