【问题标题】:Why Doesn't Message Priority Sort My Messages In RabbitMQ?为什么消息优先级不对 RabbitMQ 中的消息进行排序?
【发布时间】:2019-01-19 13:31:45
【问题描述】:

我与生产者和消费者一起运行 elixir 程序。我为我的消息设置了优先级。但优先级不起作用。

我的程序:

出版商:

Basic.publish(channel, "my_exchange", "my_queue", "1", persistent: true, priority: 2)
Basic.publish(channel, "my_exchange", "my_queue", "2", persistent: true, priority: 3)
Basic.publish(channel, "my_exchange", "my_queue", "3", persistent: true, priority: 1)
Basic.publish(channel, "my_exchange", "my_queue", "4", persistent: true, priority: 0)
Basic.publish(channel, "my_exchange", "my_queue", "5", persistent: true, priority: 4)

消费者:

def init(_) do
Connection.open(Application.get_env(:app, :rabbitmq))
{:ok, channel} = Channel.open(conn)
:ok = Basic.qos(channel, prefetch_count: 1, global: true)
{:ok, _consumer_tag} = Basic.consume(channel, "my_queue", nil, arguments: [{"x-priority", :signedint, 100}])
{:ok, %{channel: channel}}
end

def handle_info({:basic_deliver, payload, %{delivery_tag: tag, priority: priority}}, %{channel: channel} = state) do

Logger.info("Received message with payload: #{payload} and priority: #{priority}")

Basic.ack(channel, tag)

{:noreply, state}
end

发布后,我运行消费者。

预期输出:

Received message with payload: 5 and priority: 4
Received message with payload: 2 and priority: 3
Received message with payload: 1 and priority: 2
Received message with payload: 3 and priority: 1
Received message with payload: 4 and priority: 0

实际输出:

Received message with payload: 1 and priority: 2
Received message with payload: 2 and priority: 3 
Received message with payload: 3 and priority: 1
Received message with payload: 4 and priority: 0
Received message with payload: 5 and priority: 4

我做错了什么吗?消息的优先级不起作用吗?

【问题讨论】:

标签: rabbitmq elixir


【解决方案1】:

人们不应该期望消息在队列中排序,因为“队列”的基本含义是(大约任何队列都是 LIFO 或 FIFO,RabbitMQ 的队列是后者。)

对队列中的消息进行洗牌以按其在每个插入上的优先级对它们进行排序会大大降低性能。 RabbitMQ(自 3.5.0 起生效)实际允许的是:

NB尽管如此,从 3.5.0 开始 RabbitMQ 允许对队列中的消息进行排序,假设消费者得到他们进入队列的消息较慢。在这种情况下,未使用的消息将被排序。

不过,它仍然无法保证排序。优先级仅允许您让一些队列/消费者“举手”首先接收消息除非它们被阻止。否则,优先级链中的下一个将收到一条消息。

如果您需要对收入进行排序(很难想象为什么在这种情况下您会选择消息队列,但仍然如此),您必须在发送到发布者中的队列之前对其进行排序 em>,或者在从队列中收集所有预期消息之后在消费者中。

【讨论】:

  • 原来rabbit允许你优先发送消息,但没有考虑到?
  • 选项只是a keyword list,不受关键字名称限制,你可以在那里发送foo: :bar,它会被客户端过滤掉。但是priority确实是允许发送的。根据它,rabbit 将决定将此消息放入哪个队列。但由于您只有一个队列,因此此设置没有任何效果。
  • 应该补充一点,消息优先级是一个计划中的功能,但正如你所说,实现有点杂乱无章。
  • @theMayer 你有什么证明“消息优先级是计划中的功能”的参考吗?因为实现不是“有点杂乱”,所以如果没有讨厌的 hack 破坏快速可靠的消息处理的想法,这是完全不可能的。
  • 我想我错了。它实际上已经实现了——见this page
【解决方案2】:

为了消除任何疑问,您的消费者和生产者似乎同时连接和处理。发生这种情况时,消息会直接(基本上)路由到消费者,而不需要排队。

所以,RabbitMQ 工作正常,但您的期望需要稍作调整。消息优先级只会对队列中的消息进行操作,即使这样,也有可能不尊重优先级的情况(例如并行消费者)。

底线 - 不要编写要求以任何特定顺序传递消息的单元测试,因为那是 not a guarantee provided by message queuing systems

【讨论】:

  • 我运行了一个测试平台并发布了消息而不使用它们。当我在 web ui 中手动检查消息时,它们按正确的优先顺序排序。正如市长建议的那样,您的消费者可能在新消息发布之前正在消费这些消息。
【解决方案3】:

正如here所指出的,正确的队列参数是x-max-priority。您正在使用x-priority,因此您的队列没有被声明为优先级队列。

文档:https://www.rabbitmq.com/priority.html

【讨论】:

    猜你喜欢
    • 2012-05-31
    • 1970-01-01
    • 2012-02-06
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    • 2022-07-28
    • 2020-04-20
    相关资源
    最近更新 更多