将状态插件交换绑定到另一个交换不会产生任何消息

时间:2019-05-13 10:20:09

标签: python rabbitmq pika python-pika

我正在将RabbitMQ 3.5.1与 rabbit_presence_exchange (二进制分发版)和 rabbitmq_event_exchange (以帮助调试此问题)插件以及Python Pika客户端一起使用。

状态插件的工作方式是为您提供一种新的交换类型: x-presence 。当队列绑定和未绑定时(例如,路由键是用户名),使用路由键将队列绑定到此队列会生成状态通知。绑定没有路由键的队列会使您注册以接收状态通知。

这很好,我可以成功生成并接收这样的状态通知。但是,现在我想通过交换机路由状态消息。最初,我尝试使用标头交换,但是没有看到任何消息,因此我改成了扇出交换(以防我设置标头匹配不正确),但是仍然看不到任何消息通过

这是我的脚本,用于在不进行额外交换的情况下生成和接收状态消息(即,这是可行的):

#!/usr/bin/env python3
import pika
import names

MY_NAME = names.get_first_name()
PRESENCE_EXCHANGE = 'presence'

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange=PRESENCE_EXCHANGE,
                         exchange_type='x-presence')

result = channel.queue_declare('', exclusive=True)
queue_name = result.method.queue

print('My name is %s and my queue is %r' % (MY_NAME, queue_name))

channel.queue_bind(exchange=PRESENCE_EXCHANGE,
                   queue=queue_name,
                   routing_key=MY_NAME)

channel.queue_bind(exchange=PRESENCE_EXCHANGE,
                   queue=queue_name,
                   routing_key='')


def on_message(ch, method, properties, body):
    print(method, '\n', properties, '\n', body)
    exchange = method.exchange
    if exchange == PRESENCE_EXCHANGE:
        action = properties.headers['action']
        who = properties.headers['key']
        if action == 'bind':
            print(' [+] %s has come online.' % (who,))
        elif action == 'unbind':
            print(' [-] %s has gone offline.' % (who,))


channel.basic_consume(queue=queue_name,
                      on_message_callback=on_message,
                      auto_ack=True)


print(' [*] Waiting for messages. To exit press CTRL+C')
try:
    channel.start_consuming()
except KeyboardInterrupt:
    pass
finally:
    connection.close()

我修改了上面的内容,将状态消息路由到内置的扇出交换机,并将队列绑定到该交换机:

...
print('My name is %s and my queue is %r' % (MY_NAME, queue_name))

channel.queue_bind(exchange=PRESENCE_EXCHANGE,
                   queue=queue_name,
                   routing_key=MY_NAME)

channel.exchange_bind(source=PRESENCE_EXCHANGE,
                      destination='amq.fanout',
                      routing_key='')

channel.queue_bind(exchange='amq.fanout',
                   queue=queue_name)


def on_message(ch, method, properties, body):
...

我很困惑为什么交易所没有收到消息。 Erlang不是我的语言之一,因此我在尝试阅读状态显示插件的源代码以确定它是否受支持时遇到了麻烦(尽管我不知道为什么不支持它)。

如果有人有任何想法(或者更好的方式来处理RabbitMQ的存在),我很想听听。

编辑:
在这段代码和两个客户端运行的情况下,我的交换和绑定如下所示:

Listing exchanges ...
    direct
amq.direct  direct
amq.fanout  fanout
amq.headers headers
amq.match   headers
amq.rabbitmq.event  topic
amq.rabbitmq.log    topic
amq.rabbitmq.trace  topic
amq.topic   topic
presence    x-presence

Listing bindings ...
    exchange    amq.gen-6aU7qS-ikR4cLmxcT6VKDQ  queue   amq.gen-6aU7qS-ikR4cLmxcT6VKDQ  []
    exchange    amq.gen-MiyEpW9VIxD49PE9SqATFA  queue   amq.gen-MiyEpW9VIxD49PE9SqATFA  []
amq.fanout  exchange    amq.gen-6aU7qS-ikR4cLmxcT6VKDQ  queue   amq.gen-6aU7qS-ikR4cLmxcT6VKDQ  []
amq.fanout  exchange    amq.gen-MiyEpW9VIxD49PE9SqATFA  queue   amq.gen-MiyEpW9VIxD49PE9SqATFA  []
presence    exchange    amq.fanout  exchange        []
presence    exchange    amq.gen-6aU7qS-ikR4cLmxcT6VKDQ  queue   Sheila  []
presence    exchange    amq.gen-MiyEpW9VIxD49PE9SqATFA  queue   Joaquin []

1 个答案:

答案 0 :(得分:0)

我将相同的问题发布到rabbitmq-users邮件列表,并得到以下答复:

该插件暗中假定它可以与常规(队列到交换)绑定一起使用[3]。

RabbitMQ 3.5.x已经退出支持至少两年了。请升级[1] [2]。

  1. https://www.rabbitmq.com/upgrade.html
  2. https://www.rabbitmq.com/changelog.html
  3. https://github.com/rabbitmq/presence-exchange/blob/master/src/presence_exchange.erl#L72