我与生产者和消费者一起运行长生不老药计划。我为邮件设置了优先级。但是优先级不起作用。
我的程序:
发布者:
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
我做错了什么吗?邮件的优先级不起作用吗?
答案 0 :(得分:2)
由于“队列”的基本含义(几乎任何队列都是LIFO或FIFO,RabbitMQ就是后者),人们不应该期望消息在队列中被分类。 )
对队列中的消息进行混洗以按每个单个插入上的优先级对它们进行排序,这将大大降低性能。 RabbitMQ(从3.5.0版本开始生效)实际上允许的是:
NB 尽管有上述规定,但从3.5.0开始, RabbitMQ 允许排序被队列中 的消息,假设消费者得到到达队列的消息 slower 。在这种情况下,未使用的邮件将被分类。
尽管如此,它仍然没有得到保证的排序。优先级仅允许您使一些队列/消费者“举手”,以便首先接收消息,除非消息被阻止。否则,优先级链中的下一个将收到一条消息。
如果您需要对收入进行排序(很难想象为什么会在这种情况下拿起消息队列,但是仍然如此),您必须先对其进行排序,然后再发送到发布者中的队列 ,或从消费者中的队列 中收集所有期望的消息之后。
答案 1 :(得分:1)
为消除任何疑问,您的消费者和生产者似乎同时处于连接和处理状态。发生这种情况时,消息会直接(基本上)直接路由到使用者,而不会排队。
因此,RabbitMQ工作正常,但是您的期望值需要进行一些调整。邮件优先级将仅对队列中的邮件起作用,即使在这种情况下,在某些情况下(例如并行使用者),也可能不遵守优先级。
最重要的是-不要编写要求消息以任何特定顺序传递(例如How to set a charset in email using smtplib in Python 2.7?)的单元测试。
答案 2 :(得分:1)
正如here所指出的,正确的队列参数是x-max-priority
。您正在使用x-priority
,因此不会将您的队列声明为优先级队列。