扩展康斯坦丁的答案:
TLDR;
交易日志拖尾/挖掘应该对其他人隐藏。
它不是严格意义上的事件流,因为您不应该直接从其他服务访问它。它通常在将遗留系统逐渐过渡到基于微服务时使用。流程可能如下所示:
- 服务 A 向数据库提交事务
- 框架或服务轮询提交日志并将新提交作为事件映射到 Kafka
- 服务 B 订阅了 Kafka 流并从那里消费事件,而不是从数据库
更长的故事:
服务 B 没有看到您的事件来自数据库,也没有直接访问数据库。提交数据应该被投射到一个事件中。如果您更改数据库,您应该只修改您的投影规则以将新模式中的提交映射到“旧”事件格式,因此不得更改消费者。(我不熟悉 Debezium,或者它是否可以做这个投影)。
您的事件应该是幂等的,因为在分布式场景中以原子方式发布事件和提交事务是一个问题,并且工具将保证至少一次交付并具有最佳的一次性处理语义,而一次性部分是更罕见。这是由于事件来源(事务日志)与其他服务将访问的流不同,即它是分布式的。这仍然是生产者部分,Kafka->consumer 频道也存在同样的问题,但原因不同。此外,Kafka 的行为不像事件存储,因此您实现的是消息队列。
如果可能,我建议使用专用的事件存储,例如 Greg Young 的:https ://eventstore.org/ 。这通过将事件存储和消息代理集成到单个解决方案中来解决问题。通过将事件(以 JSON 格式)存储到流中,您还可以“发布”它,因为消费者订阅了该流。如果您想进一步解耦服务,您可以编写将事件从一个流映射到另一个流的投影。您的事件消耗也应该是幂等的,但是您会得到一个由聚合分区并且读取速度非常快的事件存储。
如果您也想将数据存储在 SQL DB 中,则监听这些事件并根据它们插入/更新表,只是不要使用您的 SQL DB 作为事件存储,因为它很难正确实现(失败-证明)。
对于排序部分:将从一个流中读取事件进行排序。聚合多个事件流的投影只能保证源自同一流的事件之间的排序。它通常绰绰有余。(顺便说一句,如果需要,您可以根据消费者端的某些字段对消息重新排序。)