恢复事务性发件箱模式



问题描述:

使用跨数据库和消息代理的分布式事务来原子更新数据库和发布消息/事件是不可行的。

发件箱模式描述了一种让服务以安全和一致的方式执行这两项任务的方法;它为源服务提供即时";阅读你自己的写作&";语义,同时提供跨服务边界的可靠、最终一致的数据交换。

如果我读到topicA->向topicB写一条消息(使用Kafka Streams只写一次语义(,并使用事件监听器更新数据库

这意味着,在数据库实体持久化之前,我将拥有最终的一致性,但不会丢失数据,因为我在Kafka主题中有消息(重试,直到持久化生效(。

这种模式还存在以下问题:

消息中继可能会多次发布消息。例如,它可能在发布消息后,但在记录消息发布之前崩溃。当它重新启动时,它将再次发布消息。因此,消息使用者必须是幂等的,可能是通过跟踪它已经处理的消息的ID。幸运的是,由于消息消费者通常需要是幂等的(因为消息代理可以多次传递消息(,这通常不是问题。

问题:

那么,当涉及到妥协时,什么更好呢?保持Kafka作为真相的单一来源并处理数据库中的最终一致性,还是保持Db作为真相的来源并使用Kafka充当愚蠢的消息代理?

我对你的意见很感兴趣!Thnx!

我不确定您是否真的需要流处理器。也许一个好的方法是写入DB并使用CDC连接器将数据流传输到Kafka。CDC将跟踪DB表的事务日志,并反映对kafka主题的更改。即使在连接失败的情况下,一旦重新启动,主题最终也将与数据库状态同步

最新更新