![]() |
1
7
让我们首先总结一下情况:
从表面上看,这似乎是一个适度的挑战 job shop scheduling problem 。然而,这不是你要问的。相反,您的问题似乎是针对如何确保作业只处理一次,您正在寻找RabbitMQ来提供这个答案。 所以让我们说清楚。RabbitMQ无法提供该答案,但任何其他消息队列也无法提供该答案。这有两个原因:第一,消息队列不是作业,它是作业的存放处。实际作业表示系统中状态的变化。消息队列只负责 传送 工作,而不是 正在处理 工作的一部分。
其次,消息代理只能真正做出两种交付保证中的一种。而你可以利用
外卖#1 : 显然,在交付机制而不是处理机制中寻找解决方案是徒劳的。 但是,有一个解决方案。 幂等性是一个过程的性质,重复应用该过程将导致相同的状态。无论系统在流程开始时处于何种状态,流程的输出都是相同的。一个简单的例子是一个电灯开关。假设你告诉某人把电灯开关拨100次,而这个人就这样做了。即使你知道开关最初是关闭的,你能保证在第100次翻转结束时开关的状态吗?不,因为世界上没有什么东西是完全可靠的。 但是,假设您稍微调整一下,然后说“将开关翻转到向上位置”现在,您已经定义了一个由命令生成的结束状态。在过程结束时,开关将处于“向上”状态。多次收到此命令的人员可以轻松观察开关的状态,如果开关已处于正确状态,则不采取任何行动。 如果您根据行为所达到的结果来定义自己的行为,而不是根据实现行为的过程来定义自己的行为,那么您将能够更好地拥有一个幂等系统。因此,RabbitMQ中很少提供的至少一次交付机制将在所有情况下为您工作。 外卖#2 : 根据结果而不是过程来定义你的行为。 最后一个问题是,如何做到这一点。有很多种方法,但消息系统都不是状态容器。所有计算机系统都依赖某种持久存储机制(文件、数据库、穿孔卡?)存储和检索系统状态。你应该依靠这些信息来提供提示,说明(1)需要做什么,(2)什么时候需要做,而不是(3)如何做。在开始由消息触发的工作之前,您必须通过检查当前状态来确定#3。 外卖#3 : 不要将消息队列用作状态容器。使用数据库。 |
![]() |
Danish · 确认RabbitMQ中消费者的剩余消息 6 年前 |
![]() |
iam.Carrot · RabbitMQ队列Pika的多处理 6 年前 |
![]() |
lexma · RabbitMQ发布到Exchange确认 6 年前 |
![]() |
CmdrSharp · 发布前请确保存在AMQP exchange绑定 6 年前 |
![]() |
Ermintar · 驼峰连接到具有额外参数的RabbitMQ队列 6 年前 |