失去事件在持久演员中出版的事件



在此示例中,来自Akka持久文档

    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:

    event =>
    updateState(event)
    context.system.eventStream.publish(event)
    if (lastSequenceNr % snapShotInterval == 0 && lastSequenceNr != 0)
      saveSnapshot(state)

成功持续了事件后执行。如果演员在成功发布事件之前执行此lambda时崩溃了,即在context.system.eventStream.publish(event)之前?

我是否正确理解,在这种情况下,从未发布过这种事件,这可能会导致系统状态不一致?如果是这样,是否有任何方法可以检测到这种事情发生?

[编辑]

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

  1. 如果您的应用程序被部署在一个JVM中,并且您使用默认的Akka事件发布设施,则JVM崩溃将意味着由于该设施没有任何恢复机制,因此已发布但尚未处理的所有事件都将丢失。

  2. 如果将您的应用程序部署在集群中,则仅在整个群集下降时,您将在与上述相同的情况下运行。

  3. 对于任何生产设置

我知道这个lambda:

...

成功持续了事件后执行。如果什么 演员在执行此Lambda之前坠毁 事件的成功发布,即之前 context.system.eventstream.publish(event(?

lambda是在持续存在之后运行的。演员本质上暂停了自己(将所有未决的工作放在藏匿处(,直到持久性完整,以保持一致。

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

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

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

我想这取决于您默认情况下的含义。常规演员,是的。如果您失去JVM,您将失去"常规"演员。常规演员在记忆中,实际上就像普通的Java/Scala对象一样。持续的演员当然是另一个故事。

您还说"已发布但尚未处理"。当然,那些也丢失了。任何尚未"处理"的任何东西本质上都像尚未获得数据库的JDBC语句,或者尚未传输给Kafka的消息等。设计本质上是立即将事件保存到数据库的(几乎喜欢(事务日志(,然后在已知安全持续后进行工作。

如果您的应用程序部署在集群中,则只有在整个群集下降时,您将在与上述相同的情况下运行。

一个集群本质上只是为持久演员恢复的位置。集群仍然依靠持久商店进行恢复。

(我将这个答案集中在Akka持久的演员上,答案与分布式数据之类的东西变得更加不同。(

对于任何生产设置

不一定。持续模块绝对是一个一致的选择。Kafka和Akka实际上只是具有不同目标的不同动物。Kafka实际上是酒吧/sub,Akka实质上采用了更多的事件采购方法。我已经使用两者都使用的系统,但是它们用于非常不同的目的。

相关内容

  • 没有找到相关文章

最新更新