2017-02-15 74 views

回答

1

通过在持久化实体中使用事件源以及在读取侧处理中使用偏移量跟踪来保证事件处理。

当您的持久实体命令处理程序持续发生事件时,每个事件都将与有序的"offset"一起存储。

读取端处理器通过轮询数据库来查找偏移量大于已处理的最后偏移量的事件。由于所有事件和每个读取端处理器的最新偏移量都保留在数据库中,因此即使读取端处理器崩溃并重新启动,也可确保事件不会丢失。

Lagom的卡桑德拉读出侧处理器返回CompletionStageFuture产生卡桑德拉BoundStatement实例的列表,并且这些在原子批更新与偏移更新一起执行。只要您的读取端事件处理程序的所有效果都在其生成的更新列表中捕获,就可以确保该事件将被有效处理一次:如果部分更新失败,它将自动重试。

如果您在事件处理程序中执行其他任何操作,则需要确保只有在事件处理程序成功时才会发生偏移量更新。事件处理程序返回的CompletionStageFuture必须只在副作用完成后完成,并且应该传播操作的成功或失败。请注意,如果偏移量未更新,您的事件处理程序将被重试,因此,如果您的事件处理程序与外部服务交互,则需要确保它是幂等的。

您还应该意识到最终一致性会如何影响事物。该akka-persistence-cassandraconfiguration reference有一些细节:

返回的事件流由偏移(时间戳),其对应 于相同的顺序写入日志存储的事件,与不准确性由于时钟有序不同间偏差 节点。以尽力而为的方式返回相同的流元素(以相同的顺序)以执行查询的多个 。该查询使用Cassandra Materialized 视图进行查询并且最终一致,因此不同的查询可能会针对最新事件看到不同的 事件,但最终结果将按时间戳 (Cassandra timeuuid列)排序。为了弥补最终一致性,查询 延迟不读取最新事件,此延迟的持续时间由此 配置属性定义。

然而,这只是尽力而为和网络分区 或其他的东西,可能会延迟事件可以按照不同的顺序 交付的物化视图的更新的情况下(不完全由他们的时间戳)。

重要的结论是,如果最终一致性的等待时间大于配置最终一致性延迟(可能由于卡桑德拉节点之间的网络分区)更长的时间,存在正在“丢失”事件的可能性。读出侧处理器可能已经处理的新事件,并在存储前的旧事件已交付,它是从阅读节点的偏移。您可能需要相应地调整您的配置。