py-amqp不存在如何检测交换

时间:2013-02-19 22:10:35

标签: python amqp py-amqplib

我希望能够在向AMQP提交邮件时检测交换是否存在。

请考虑以下示例。

#!/usr/bin/python

import amqp
from time import sleep

conn = amqp.Connection(host="localhost:5672", userid="guest", password="guest", virtual_host="/")
outgoing = conn.channel()
message = amqp.Message("x")


while True:
    print "publish message."
    outgoing.basic_publish(message,exchange="non-existing",routing_key="fubar")
    sleep(1)

此脚本将继续发布到交换,但如果交换不存在则不会引发任何错误。当交换存在时,消息到达。

#!/usr/bin/python

import amqp
from time import sleep

conn = amqp.Connection(host="localhost:5672", userid="guest", password="guest", virtual_host="/")
outgoing = conn.channel()
message = amqp.Message("x")


while True:
    print "publish message."
    outgoing.basic_publish(message,exchange="non-existing",routing_key="fubar")
    outgoing.wait()
    sleep(1)

当我添加outgoing.wait()时,会引发amqp.exceptions.NotFound,这就是我想要的。但问题是,如果在这种情况下交换存在,则消息到达但是outgoing.wait()阻止我的循环。 (我可以在一个单独的线程中运行outgoing.wait(),但我不想这样做。)

如何处理?

任何建议提示指示欢迎

谢谢,

2 个答案:

答案 0 :(得分:4)

如果要查明是否存在交换,请使用exchange_declare方法并将passive标志设置为True。将passive标志设置为True将阻止服务器尝试创建交换,而是在交换不存在时抛出错误。

import amqp
from amqp.exceptions import NotFound

conn = amqp.Connection(host="localhost:5672", userid="guest", password="guest",
                       virtual_host="/")
outgoing = conn.channel()
try:
    outgoing.exchange_declare("fubar", "", passive=True)
except NotFound:
    print "Exchange 'fubar' does not exist!"

如果您真正感兴趣的是确保在发布之前存在交换,请在进入发送循环之前声明它。如果交换已经存在,则不会发生任何事情如果交换不存在,则会创建。

import amqp

conn = amqp.Connection(host="localhost:5672", userid="guest", password="guest",
                       virtual_host="/")
outgoing = conn.channel()
outgoing.exchange_declare("fubar", "direct")

以下是您正在使用的amqp库中exchange_declare方法声明的链接:

https://github.com/celery/py-amqp/blob/master/amqp/channel.py#L460-L461

答案 1 :(得分:1)

不幸的是,需要阻止调用来检查basic_publish()中的异常。但是,您可以执行的操作是在进入异步循环之前运行阻塞调用一次:

# send a test message synchronously to see if the exchange exists
test_message = amqp.Message('exchange_test')
outgoing.basic_publish(test_message,exchange="non-existing",routing_key="fubar")
try:    
    outgoing.wait()
except amqp.exceptions.NotFound:
    # could not find the exchange, so do something about it
    exit()

while True:
    # fairly certain the exchange exists now, run the async loop
    print "publish message."
    outgoing.basic_publish(message,exchange="non-existing",routing_key="fubar")
    sleep(1)