Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 如何确保只有一个消费者实际使用已发布的消息?_Spring Boot_Rabbitmq_Publish Subscribe_Distributed System - Fatal编程技术网

Spring boot 如何确保只有一个消费者实际使用已发布的消息?

Spring boot 如何确保只有一个消费者实际使用已发布的消息?,spring-boot,rabbitmq,publish-subscribe,distributed-system,Spring Boot,Rabbitmq,Publish Subscribe,Distributed System,我将Rabbitmq与微服务体系结构结合使用。我的许多用例都使用topic和directexchange,而且效果很好。然而,我有一个用例,我必须从数据库中删除一条记录。当我删除记录时,需要调用几个其他服务,并维护/删除引用的记录。我可以通过使用直接交换简单地调用这些服务来实现这一点,但我了解到这是编舞,而不是编排。这意味着我应该实现发布/订阅模式(rabbitmq中的扇出)。 我的问题是,如果在分布式系统中使用发布/订阅模式,如何确保只有一个服务实例使用发布的消息 我想您应该为每个服务都有一个

我将Rabbitmq与微服务体系结构结合使用。我的许多用例都使用topic和directexchange,而且效果很好。然而,我有一个用例,我必须从数据库中删除一条记录。当我删除记录时,需要调用几个其他服务,并维护/删除引用的记录。我可以通过使用直接交换简单地调用这些服务来实现这一点,但我了解到这是编舞,而不是编排。这意味着我应该实现发布/订阅模式(rabbitmq中的扇出)。
我的问题是,如果在分布式系统中使用发布/订阅模式,如何确保只有一个服务实例使用发布的消息

我想您应该为每个服务都有一个单独的队列,该服务实例应该得到关于数据库记录删除的通知。交换器在所有队列中放置消息的副本。服务实例竞争对专用队列的访问(只有一个实例获得消息)

您的问题与发布-订阅的关系不大,与基本消息处理的关系不大。最基本的问题是您是否可以保证一个操作只执行一次。简而言之,您可能希望使用直接交换,以便消息进入一个队列并由一个(可能是多个)使用者处理

很长的答案是“仅一次”无法保证,因此您需要将此部分作为设计的一部分

背景

最好的做法是将消息处理设为幂等运算。事实上,幂等性是几乎所有外部接口的关键设计假设(我认为它在内部接口中同样重要)

此外,您应该知道,不可能保证“一次准确”交付。从数学上讲,这是无法保证的。相反,您可以有两件事中的一件(相互排斥):