使用事件(RabbitMQ)同步微服务

4
我们正在使用微服务架构在nodejs中实现Web-API。每个服务都会公开HTTP端点,以便应用程序/网站可以与其互动。为了同步不同的数据库,我们目前正在使用RabbitMQ。微服务可以在fanout交换器上发布消息,每个订阅的微服务都会接收到该消息。
这种架构存在两个问题:
1. 如果我们想添加一个微服务的第二个实例(例如负载均衡),那么如果第二个服务订阅相同的fanout交换,则消息将被消费两次。 2. 无论是确认在fanout交换中不起作用还是我做错了什么,当我在没有订阅者的fanout交换上发布消息时,消息会立即消失而未被确认。
这导致我的问题。RabbitMQ是否是微服务同步的好选择,或者我们应该改变我们的架构。以下是我希望它能够工作的简短示例:
1. 用户创建新账户。 2. auth-mc将用户插入其数据库并发布'user.created'事件。 3. a1-mc、a2-mc(相同的mc,只是负载均衡)和b1-mc都是交换的订阅者。a1或a2以及b1都会接收事件并将用户插入各自的数据库中。 4. 只有在确认后,事件才会从每个微服务的队列中删除。
这样,我可以确保每个微服务(负载均衡或非负载均衡)都会收到消息一次。是否可以使用RabbitMQ实现这样的模式?
编辑:如果有任何建议,也希望了解有关微服务的良好文献。
1个回答

2
让我们使用topic交换机代替fanout以达到你的目的。只有一个消费者会收到消息,而不是所有消费者。你可以根据routing_key参数将消息路由到不同的消费者。例如,你有一个交换机,你有三个不同的队列绑定到这个交换机,使用相同的路由键。你的消息将被复制到每个队列中!来自不同微服务的消费者可以分别读取消息并执行它们需要的操作。直到你确认它,消息才不会被丢弃,但是最好的做法是使用TTL推送消息。

这似乎按预期工作,非常感谢! - Lucas
还有一些事情我不确定。您是为每个微服务创建一个通道,还是为每个订阅/发布创建一个通道?对于未确认或已过期的消息,您会怎么处理?如果我只是重新排队这些消息,服务可能会反复获取损坏的消息并陷入死锁。我应该冒险继续,回滚所有更改,还是将消息重新排队到死信交换中? - Lucas
1
你每个发布/订阅创建一个交换机,但每个微服务都有一个队列。你的生产者将消息推送到交换机(这是它的单一点),消费者将其队列绑定到交换机并从此接收消息。如何处理数据丢失、竞争条件等问题,这取决于情况。你有不同的方法来解决这个问题,比如构建RPC模型、锁定机制等。 - Vadim Kharitonov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接