将 Kafka Consumer 和 API 服务分开或合并在一起

问题描述 投票:0回答:3

最近阅读了基于事件的架构之后,我想将我的架构更改为利用这些优势的架构。

我有两个公开 API 的服务(crud、graphql),每个服务都基于不同的实体并使用不同的数据库。

但是,现在每当有人删除服务 A 中的某种类型的行时,我都需要删除服务 B 中的耦合行。

所以我将 Kafka 添加到我的设计中,每当我删除服务 A 中的实体时,它都会向 Kafka 发布一条通知消息。

在服务 B 中,我当前正在使用相同的主题,因此每当收到新消息时,服务还将处理匹配实体的删除,因为它已经可以访问该表,因为同一服务已经向用户公开了 CRUD API。

我不确定的是,将 Kafka Consumer 和 API 放在同一个服务中是否是一个好的设计。这与微服务的单一责任点相矛盾,服务的某一部分出现问题,很可能会影响第二部分。

但是,创建新服务也会给我带来问题 - 我将有两个不同的服务访问同一个表,并且每当对表或数据库进行更改时,我必须确保始终将它们维护在一起。

发生此类事件的最佳做法是什么?不同的服务之间存在数据耦合是不可避免的吗?还是将同一个服务用于两个相似的用途并不是那么糟糕。

apache-kafka architecture microservices
3个回答
0
投票

使用 Kafka 没有任何问题...但是,您可以对点对点服务通信执行相同的操作(JSON-RPC / gRPC)。

您似乎要问的真正问题是双重写入或竞争条件导致数据不一致。

虽然您可以使用单个消费者组和一个主题分区来保留对这些事件感兴趣的消费者之间的顺序和锁定,但这并不会阻止“其他消费者组”与数据库交互以执行相同的操作。因此,Kafka 本身并不能帮助解决这个问题。 您需要外部分布式锁(例如,此处可以使用 Zookeeper)来隔离数据库客户端,同时针对数据库客户端执行操作。

对于最初的问题,Kafka Connect 提供了一个 API,并且

也是

一个生产者和消费者客户端(并且建议用于数据库交互)。 Confluence SchemaRegistry、KSQLdb 等也是如此


0
投票

对于消费者代码是否应该与“服务”代码共享相同的代码库/存储库,可能存在不同的意见。有些人认为最好将存储库范围限制为单个“可执行文件”,其他人认为保留域范围并将所有内容都放在单个存储库中是有益的。我可能属于后一组,但对此没有很强的看法。我认为更重要的是拥有一个指向所涉及的存储库等的域的中央文档/维基。


0
投票

假设您有多个具有 REST API 的服务,例如服务 A 连接到数据库 A,服务 B 连接到也具有 REST API 的数据库 B,并且您希望使用 kafka 或任何消息代理(如 RabbitMQ)集成基于事件的框架。

注意 - 无论是单个存储库还是多个存储库都没有关系。它只需要有单独的部署,可以根据您的用例处理负载。

这些服务的部署应该是分开的,以遵循微服务中的单一责任点。

现在可能会导致数据不一致,因为消费者有一个单独的部署,你可能需要它连接到具有某种模式类型的服务 A 的数据库。

在这种情况下,最好通过创建一个包将架构放在一个位置,该包将为您创建架构,并且您可以从那里导出它。

这两个服务,即消费者和您的其余 API 服务都将导入相同的数据库模式。

这将解决管理表的单独模式的问题。

© www.soinside.com 2019 - 2024. All rights reserved.