我们有一个微服务架构,其中Kafka用作服务之间的通信机制。一些服务具有自己的数据库。假设用户调用服务A,这将导致在该服务的数据库中创建一条记录(或一组记录)。此外,此事件应作为Kafka主题的一项报告给其他服务。确保仅在成功更新Kafka主题(实质上是围绕数据库更新和Kafka更新创建分布式事务)时才写入数据库记录的最佳方法是什么?
我们正在考虑使用spring-kafka(在Spring Boot WebFlux服务中),我可以看到它具有KafkaTransactionManager,但是据我了解,这更多地是关于Kafka事务本身(确保Kafka生产者和消费者之间的一致性),而不是在两个系统之间同步事务(请参阅此处:“ Kafka不支持XA,您必须处理在Kafka tx回滚时DB tx可能提交的可能性。”)。另外,我认为此类依赖于Spring的事务框架,至少就我目前所知,该框架是线程绑定的,如果使用反应性方法(例如WebFlux)在操作的不同部分执行该方法,则该类将不起作用。不同的线程。(我们正在使用react-pg-client,因此手动处理事务,而不是使用Spring的框架。)
我能想到的一些选择:
不要将数据写入数据库:仅将其写入Kafka。然后使用使用者(在服务A中)更新数据库。看来这可能不是最有效的,并且会出现问题,因为用户调用的服务无法立即看到它应该刚刚创建的数据库更改。不要直接写到Kafka:只写数据库,并使用Debezium之类的东西向Kafka报告更改。这里的问题是,更改是基于单个数据库记录的,而要存储在Kafka中的业务重要事件可能涉及多个表中数据的组合。首先写入数据库(如果失败,则不执行任何操作,仅引发异常)。然后,在写入Kafka时,假设写入可能会失败。使用内置的自动重试功能可以使其保持一段时间。如果最终完全失败,请尝试写入死信队列,并为管理员创建某种手动机制以将其解决。并且,如果写入DLQ失败(即Kafka完全关闭),只需以其他方式记录(例如,写入数据库),然后再次创建某种手动机制供管理员进行分类即可。是否有人对以上内容有任何想法或建议,或者能够纠正上述假设中的任何错误?