【问题标题】:RabbitMQ - Single concurrent worker per routing keyRabbitMQ - 每个路由键单个并发工作者
【发布时间】:2016-12-20 19:01:44
【问题描述】:

对 RabbitMQ 很陌生,我正在尝试使用它来实现我所需要的。

我正在寻找 Worker Queues 模式,但有一个警告。我希望每个路由键只有一个工作人员同时运行。

一个澄清的例子:

如果我按顺序发送以下带有路由键的消息:aabc,我希望只有 3 个工作人员同时运行。当收到第一条a 消息时,工作人员会捡起它并处理它。

当接收到下一个a 消息并且前一个a 消息仍在处理(未确认)时,新的a 消息应该在队列中等待。当收到bc 消息时,它们各自都有一个工作人员处理它们。当第一条a 消息被确认后,任何工作人员都可以接收下一条a 消息。

以自然的方式使用 RabbitMQ 是否可以实现该模式(无需在我这边编写任何应用程序代码来处理锁定和其他东西......)

编辑:

另一个澄清。所有工作人员都可以并且应该处理所有消息,并且我不希望每个工作人员都有一个队列,因为我想在他们之间分担负载,并且发布者不知道哪个工作人员应该处理消息。但我确实想确保没有 2 个 Worker 同时处理共享相同密钥的消息。

例如,如果我有一个发布者发布带有 userId 字段的消息,我想确保没有 2 个 Worker 正在同时处理具有相同 userId 的消息。

编辑 2

扩展userId 示例。假设我有一个发布者和 3 个工人。发布者发布如下消息:{ userId: 1, text: 'Hello' },不同的userIds。我的 3 个工作人员都对这些消息做同样的事情,所以我可以让他们中的任何一个处理进来的消息。但我想要实现的是只有一个工作人员同时处理来自某个用户的消息时间。如果一个 Worker 收到一条带有 userId 1 的消息并且仍在处理它,并且收到另一条带有 userId 1 的消息,我想确保没有其他 Worker 接收到该消息。但是其他带有不同userIds 的消息应该由其他可用的Worker 处理。

userIds 事先不知道,发布者不知道有多少工作人员或关于他们的任何具体信息,他只是想安排消息进行处理。

【问题讨论】:

    标签: multithreading rabbitmq message-queue rabbitmq-exchange


    【解决方案1】:

    路由键无法满足您的要求,而是通过一些设置内置于队列中。

    如果您为a 消息定义“queue_a”,为b 消息定义“queue_b”等,那么您可以让任意数量的消费者连接到它。

    RabbitMQ 只会将给定消息传递给给定队列的单个消费者。

    它与单个队列上的多个消费者一起工作的方式是消息的基本循环式调度。也就是说,第一条消息将被传递给一个消费者,而下一条消息(假设第一个消费者仍然很忙)将被传递给下一个消费者。

    因此,这应该满足将消息传递给队列的任何给定使用者的需求。

    为确保您的消息有平等的机会到达任何消费者(并且并非一直都传递给同一个消费者),您应该进行一些其他设置。

    首先,确保将消息使用者no ack 设置为false(有时称为“自动确认”)。这将迫使您从代码中ack 发送消息。

    最后,将消费者的“消费者预取”限制设置为 1。

    使用这种设置组合,单个消费者将检索单个消息并开始处理它。当该消费者工作时,队列中等待的任何消息都将被传递给其他消费者(如果有的话)。如果没有可用的消息,消息将在队列中等待,直到有可用的消费者。

    有了这个,你应该能够在给定的队列上实现你想要的行为。

    ...

    请记住,这仅适用于队列。不能以这种方式管理路由密钥。来自交换的所有匹配的路由键都会导致将消息的副本发送到目标队列。

    【讨论】:

    • 在我看来,这个遮阳篷是对的。但是对于队列来说,遮阳篷甚至是否定的,因为问题是“任何工作人员都可以接收下一条消息”,这是不可能的。在这种情况下,每个队列只有一个工作人员和一个它作用的路由键。因此,每次同一个工人收到下一条消息时。
    • 谢谢,德里克,但@slowjack2k 我的意思是正确的。我给工人的所有信息都是一样的,我不关心(也不想关心)哪个工人收到了信息。我只想确保只有一个工作人员基于某个键(我为每条消息生成)对某些消息进行操作。
    • @NetanelG 这两个陈述不能放在一起All my messages for the workers are the samemessages based on some key (that I generate per message) Aslo Derick 的回答对于您以您提出的方式提出的问题是正确的,但基于此评论,我认为您应该编辑它。
    • @cantSleepNow 你的评论是对的,我没有正确表达自己。所有消息都是相同的,我的意思是它们的处理方式相同,而不是它们具有相同的内容。关于这个问题,正如 slowjack2k 所说,我说过任何工作人员都可以接收任何消息,但我会尽量在问题中说得更清楚。
    • 啊——你是对的。我误读(或忘记了)这部分问题。在这种情况下,您不需要为给定的消费者使用“独占”选项。我会更新我的答案
    猜你喜欢
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    相关资源
    最近更新 更多