问题描述:
使用跨越数据库和消息代理的分布式事务来自动更新数据库和发布消息/事件是不可行的。
发件箱模式描述了一种让服务以安全和一致的方式执行这两个任务的方法;它为源服务提供即时“读取您自己的写入”语义,同时提供跨服务边界的可靠、最终一致的数据交换。
如果我从 topicA 读取消息 -> 向 topicB 写入消息(使用 Kafka Streams 的语义恰好一次)并使用事件监听器更新数据库,会有什么缺点?
这意味着在数据库实体被持久化之前,我将具有最终的一致性,但不会丢失数据,因为我在 Kafka 主题中有消息(重试直到持久性工作)。
这种模式还存在以下问题:
消息中继可能会多次发布消息。例如,它可能会在发布消息之后但在记录它已经这样做的事实之前崩溃。当它重新启动时,它将再次发布消息。因此,消息消费者必须是幂等的,可能通过跟踪它已经处理的消息的 ID 来实现。幸运的是,由于消息消费者通常需要是幂等的(因为消息代理可以多次传递消息),这通常不是问题。
问题:
因此,当涉及到妥协时,什么更好,保持 Kafka 作为单一事实来源并处理数据库中的最终一致性,还是将 Db 作为事实来源并使用 kafka 作为愚蠢的消息代理?
我对你的意见很感兴趣!谢谢!