首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >崩溃时在Persistent Actor中丢失事件发布

崩溃时在Persistent Actor中丢失事件发布
EN

Stack Overflow用户
提问于 2019-05-24 18:58:33
回答 1查看 120关注 0票数 0

在这个来自Akka persistance documentation的示例中

代码语言:javascript
复制
    val receiveRecover: Receive = {
    case evt: Evt                                 => updateState(evt)
    case SnapshotOffer(_, snapshot: ExampleState) => state = snapshot
    }

    val snapShotInterval = 1000
    val receiveCommand: Receive = {
    case Cmd(data) =>
      persist(Evt(s"${data}-${numEvents}")) { event =>
        updateState(event)
        context.system.eventStream.publish(event)
        if (lastSequenceNr % snapShotInterval == 0 && lastSequenceNr != 0)
          saveSnapshot(state)
      }
    case "print" => println(state)
    }

我理解这个lambda:

代码语言:javascript
复制
    event =>
    updateState(event)
    context.system.eventStream.publish(event)
    if (lastSequenceNr % snapShotInterval == 0 && lastSequenceNr != 0)
      saveSnapshot(state)

在成功持久化事件后执行。如果参与者在成功发布事件之前(即在context.system.eventStream.publish(event)之前)执行此lambda时发生崩溃,该怎么办

我是否正确理解了,在这种情况下,事件永远不会发布,这可能会导致系统的状态不一致?如果是这样,有没有办法检测到发生了这样的事情?

编辑

另外,如果你在你的系统中使用事件发布,如果我错了,请纠正我:

  1. 如果您的应用程序部署在一个JVM中,并且您使用默认的Akka事件发布工具,那么JVM崩溃将意味着所有已发布但尚未处理的事件都将丢失,因为该工具没有任何恢复机制。
  2. 如果您的应用程序部署在集群中,那么只有在整个集群宕机的情况下,您才会在与上面相同的情况下运行。对于任何生产设置,您都应该为event publishing/consuming.

配置类似

  • 的内容
EN

回答 1

Stack Overflow用户

发布于 2019-05-28 07:45:11

我知道这个lambda:

..。

在成功持久化事件后执行。如果在成功发布事件之前,即在context.system.eventStream.publish( event )之前执行这个lambda时,actor崩溃了怎么办?

lambda在状态被持久化之后运行。而参与者实际上会挂起自己(将所有挂起的工作放在存储库中),直到持久化完成,以便保持一致。

我的理解是否正确,在这种情况下,事件永远不会发布,这可能会导致系统状态不一致?

不,由于上述原因,它将保持一致。

如果您的应用程序部署在一个JVM中,并且您使用默认的Akka事件发布工具,那么JVM崩溃将意味着所有已发布但尚未处理的事件都将丢失,因为该工具没有任何恢复机制。

我猜这取决于你所谓的默认事件发布。普通演员,是的。如果你失去了JVM,你就失去了“普通的”参与者。常规参与者位于内存中,本质上类似于普通的Java/Scala对象。执着的演员,当然是一个不同的故事。

您还可以说“已发布但尚未处理”。当然,这些也会丢失。任何没有“处理”的东西本质上就像数据库还没有接收到的JDBC语句,或者没有传输到Kafka的消息,等等。其设计本质上是将事件立即保存到数据库中(几乎像事务日志),然后在知道它可以安全地持久化之后执行工作。

如果您的应用程序部署在集群中,那么只有在整个集群宕机的情况下,您才会在与上面相同的情况下运行。

集群本质上只是为持久化的参与者提供了一个恢复的地方。群集仍然依赖持久存储进行恢复。

(我将这个答案集中在Akka Persistent Actors上,答案随着分布式数据的变化而变得更加多样化。)

对于任何生产设置,您都应该为事件发布/消费配置类似Kafka的内容。

不一定。persistent模块绝对是一个一致的选择。卡夫卡和阿卡实际上是不同的动物,有着不同的目标。Kafka是有效的发布/订阅,Akka本质上采取了一种更多的事件来源方法。我曾经使用过使用这两种方法的系统,但它们使用它们的目的截然不同。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56291274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档