【问题标题】:Consume message only once from Topic per listeners running in cluster每个在集群中运行的侦听器仅从主题消费一次消息
【发布时间】:2016-08-11 02:22:49
【问题描述】:

我正在实施领域事件基础架构,但该项目不允许任何消息传递基础设施(金融服务客户端),因此在 Hazelcast 主题和 ExecutorService 中找到了替代方案,

但问题是在集群中运行时,消息将被传递给将在集群中运行的侦听器,因此对于 2 个集群,我们在 2 个 jvm 中运行相同的侦听器,消息消费两次并采取行动,假设域事件应该执行一些非幂等操作,例如信用一些忠诚度积分,除非我明确地维护一个域事件的踪迹并检查每次我收到一个事件时,我最终会记两次,“任何建议实现这一点而不必在底层编写那些样板”,或者是否有这种实现的已知模式。

编辑:同时我也在评估Hazelcast ExecutorService 建议Here

【问题讨论】:

    标签: java jms hazelcast jms-topic


    【解决方案1】:

    您描述的用例可以通过使用 Hazelcast 的队列而不是主题来解决。使用主题的主要原因是如果您对多个(可能是独立的)消费者获得相同的消息感兴趣。您的要求听起来像是您对只有一个消费者收到消息感兴趣,这就是队列的用途,请参阅the Hazelcast documentation for Queues

    【讨论】:

    • 我可以尝试进一步扩展需求,选择主题是因为必须将消息传递给多个订阅者,但是如果订阅者在多个 jvm 中运行,则应该只处理订阅者的一个实例消息。
    • 在这种情况下,您可以通过外部锁定以多种方式解决此问题,即您必须确保您处理的消息当前没有在其他地方处理。一种解决方案可能是使用所有侦听器都可以访问的分布式映射,并结合分布式锁。每个侦听器都获取锁,检查消息是否已经被处理或当前正在处理(映射中的消息 id),如果没有,它会在映射中放置一个条目(IN_PROCESS 或类似的东西)。然后侦听器释放锁,并根据地图状态处理或不处理它。
    • 并且在成功处理后,各自的监听器再次获取锁,将映射条目更新为 PROCESSED 或类似的,仅此而已。您唯一需要确保的是,地图中的条目会在某个时间点过期,否则您将耗尽内存;)
    • 这里的挑战是消息 ID。对于大型消息传递系统,没有可用于标识特定消息的唯一 ID 的概念。 (比如 MQTT)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 2019-04-04
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    相关资源
    最近更新 更多