【问题标题】:Same event processing in multiple instances of a java servicejava服务的多个实例中的相同事件处理
【发布时间】:2019-12-15 23:13:28
【问题描述】:

假设您在使用 java/spring/hibernate 的微服务设置中拥有相同服务的两个或多个实例。为了让这个例子更清楚一点,让我们假设我们有:

  • books 服务,创建/更新书籍
  • book-details 服务将处理书籍的详细信息
  • tasks 服务将为创建/更新的书籍创建一些任务

我正在尝试解决并找出处理此问题的最佳方法与以下情况有关:

  • 多次发出相同的事件(例如第 1 本书已更新)
  • book 1 updated 更新事件由book-details 服务选择,在其处理后将发出book 1 details updated event。这两个事件都将在tasks 服务中处理。

tasks 最终会做的是检查是否存在并为此主题创建或删除任务(在本例中为第 1 册)。这可能是一个复杂的操作,不能是原子数据库事务。

鉴于多个实例订阅同一个主题,同一事件可能被多个实例同时处理导致完整性约束错误(由于唯一索引)。

如何正确处理?理想的情况是实例#1 处理book 1,但不阻止实例#2 处理book 2。虽然相同的 book 1 事件正在为同一个实例排队。

【问题讨论】:

  • 使用jms框架并开始使用认知模式?
  • 理想的解决方案是为此提供与应用程序级别无关的解决方案

标签: java spring hibernate microservices


【解决方案1】:

您可以在您的情况下使用分布式锁和映射。以榛树为例。

锁 - https://docs.hazelcast.org/docs/3.0/manual/html/ch02s07.html.

地图 - https://docs.hazelcast.org/docs/3.0/manual/html/ch02.html#Map

  1. 通过事件(或事件 id..)获取锁定 - 以防止在不同实例上执行
  2. 检查地图(例如IMap<BookEvent, boolean wasProcessed>),如果此事件已在另一个实例上处理 - 返回
  3. 处理您的活动
  4. 将事件和状态放到地图上
  5. 解锁

【讨论】:

  • 谢谢!作为替代方案,也可以使用 redisson,它在 redis 之上提供了一组类似的抽象。
猜你喜欢
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 2013-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-24
  • 1970-01-01
相关资源
最近更新 更多