众所周知,RabbitMq交换机和队列的绑定方式有3种
Fanout Exchange– 不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。 很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。
Direct Exchange– 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列 绑定到该交换机上要求路由键 “dog”,则只有被标记为“dog”的消息才被转发,不会转发dog.puppy,也不会转 发dog.guard,只会转发dog。
Topic Exchange– 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。因 此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”。
具体介绍:
http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Messaging_Tutorial/sect-Messaging_Tutorial-Initial_Concepts-Fanout_Exchange.html
==============================================================================================================
我现在的代码是使用fanout的,当我有多个绑定关系,多个队列的时候这个就不合适了,因为我就必须要申明多个交换机,这样当业务越来越大的时候会很吃力,所以我打算把它改造成topic
改造其实很简单,就把fanout改成topic,然后简单的改造一下交换机和队列的声明方式就行。
但是问题来了,当我改造的完以后死活都不能运行,老是报错:
cannot redeclare exchange 'x1' in vhost '/' with different type, durable or autodelete value", (40, 10), 'Channel.exchange_declare
这是为啥呢?我没有重复声明x1啊。挠头,纠结。。。。。
网上google了半天,没找出个所以然来,看代码也没发现问题,然后重看那篇文章 :
[RabbitMQ+Python入门经典] 兔子和兔子窝
当看到 “队列和交换机有一个创建时候指定的标志durable,直译叫做坚固的。durable的唯一含义就是具有这个标志的队列和交换机会在重启之后重新建立,它不表示说在队列当中的消息会在重启后恢复。” 时候有了想法。
是不是因为 我之前已经申明了x1,它的绑定关系是fanout了,并且由于是坚固模型,退出的时候也并没有删除这个名为x1的交换机,所以现在重新声明的时候就出错了呢?
于是用 管理RabbitMq的命令 rabbitmqctl list_exchanges 查看rabbitMQ里面已经声明的交换机,果然 出现了这么一行 : x1 fanout
问题找到了,那么我们下一步要做的就是先删除这个交换机,我们用 exchange_delete('x1'),然后再用rabbitmqctl list_exchanges 的时候已经是没有x1了,证明我们删除成功。
然后再运行改造完的代码,OK ,顺利执行
==============================================================================================================
调试bug是很费体力的,不过最终搞定的时候还是很happy的。特写本文以纪念之