2

这对于订阅流中所有事件的投影来说很容易,您只需保留应用在读取模型上的最后一个事件的版本。但是当投影是多个流的复合时,你会怎么做?您是否保留参与投影的每个流的版本。但是,如果您不订阅所有事件,那么差距又如何呢?最多您可以断言版本大于上一个。其他人如何处理这个问题?您是否响应每个事件并升级版本?

4

3 回答 3

2

对于 EventStore,我建议使用该$all流作为任何读取模型订阅的默认流。

我使用了本质上生成给定实体类型快照的类别流,但我停止这样做,因为读取模型服务于不同的目的。

可能不希望使用$all流,因为它也可能获取不是域事件的事件。集成事件就是一个例子。在这种情况下,向事件契约或元数据添加一些属性可能有助于创建一个内部 (JS) 投影,该投影将为域事件或在这方面的任何事件类别创建一个特殊的所有流,您可以在其中订阅。您还可以使用否定条件,例如,过滤掉所有系统事件以及原始流名称以 . 开头的事件Integration

于 2019-07-09T16:22:55.867 回答
1

除了以正确的顺序处理消息之外,您还面临在重新启动后恢复投影的问题 - 您如何确保在重新启动时从正确的位置开始?

最简单的选择是使用事件存储或消息代理,它们既保证顺序又提供某种全局流位置字段(例如全局事件编号或带有消歧组件的有序时间戳,例如 MongoDB 的 Timestamp 类型)。您直接从存储中提取事件的事件存储(例如 eventstore.org 或基于数据库构建的本地存储)倾向于保证这一点。此外,Apache Kafka 等一些消息代理保证排序(同样,这是基于拉的)。理想情况下,您希望至少一次订购交货。

这种方法限制了写入的可扩展性(读取可以很好地扩展,使用只读副本) - 您可以以各种方式跨多个事件存储实例分片您的流,然后您必须在每个分片的基础上跟踪位置,这增加了一些复杂性。

如果您没有这些订购、交货和位置保证,您的生活会更加艰难,并且可能很难使系统完全可靠。你可以:

  • 收到消息后,在处理它们之前先保留一段时间,以允许其他消息到达
  • 有代码来检测丢失或乱序的消息。正如您所提到的,这仅在您收到具有全局序列号的所有事件或跟踪所有流版本号时才有效,即使这样,它在所有情况下也不可靠。
于 2019-06-12T10:56:47.787 回答
0

对于每个单独的流,您可以通过从知道正确顺序的数据存储中获取它们来保持它们的顺序。一种思考方式是查询数据存储,然后返回文档消息

回顾 Greg Young 的Polyglot Data演讲可能会有所帮助。

至于多流中的事件同步;您需要认识到的是,不同流中的事件本质上是并发的。

如果您将happens-before数据编码到消息中,则可以在不同的流之间进行一些松散的协调。“事件 B 响应事件 A 而发生,因此 A 发生在 B 之前”。这会让你得到部分排序。

如果您确实需要对所有地方的所有东西进行全面排序,那么您需要研究像Lamport Clocks这样的模式。

于 2019-06-06T12:29:10.883 回答