saf*_*afl 9 python routing amqp rabbitmq
RabbitMQ和Python是否可以进行基于内容的路由?
AMQP标准和RabbitMQ声称支持基于内容的路由,但是有没有支持指定基于内容的绑定等的Python库?
我目前使用的库(py-amqplib http://barryp.org/software/py-amqplib/)似乎只支持基于主题的路由和简单的模式匹配(#,*).
Fab*_*olm 18
答案是"是",但还有更多...... :)
让我们首先就基于内容的路由的含义达成一致.有两种可能的含义.有人说它是基于消息的标题部分.其他人说它基于消息的数据部分.
如果我们采用第一个定义,这些或多或少都是我们做出的假设:数据在某个地方出现,并通过某个软件发送到AMQP代理.我们假设这个软件足够了解数据,以便将键值(KV)对放在描述内容的消息的标题中.理想情况下,发件人也是数据的生产者,因此它拥有我们想要的尽可能多的信息.假设数据是图像.然后我们可以让发件人将KV对放在邮件头中,如下所示:
width=1024
height=768
mode=bw
photographer=John Doe
Run Code Online (Sandbox Code Playgroud)
现在我们可以通过创建适当的队列来实现基于内容的路由.假设我们在黑白图像上执行单独的操作,在彩色图像上执行单独的操作.我们可以创建两个队列,一个用于接收消息,mode=bw
另一个用于接收消息mode=colour
.然后我们有单独的客户端侦听这些队列.代理执行路由,我们的客户端中没有任何东西需要知道路由.
如果我们采用第二个定义,我们将采用不同的假设.我们假设数据在某处出现,并通过某个软件发送给AMQP代理.但是我们假设要求该软件应该用KV对填充标题是不明智的.相反,我们希望根据数据本身做出路由决策.
AMQP中有两个选项:您可以决定为特定数据格式实施新交换,也可以将路由委派给客户端.
在RabbitMQ中,有直接(1对1),扇出(1到N),标头(标头过滤的1到N)和主题(主题过滤的1到N)交换,但是你可以根据AMQP标准实现自己的.这需要阅读大量RabbitMQ文档并在Erlang中实现交换.
另一个选择是在Python中创建一个AMQP客户端,用于侦听特殊的"内容路由队列".每当消息到达队列时,您的路由器 - 客户端都会接收它,执行做出路由决策所需的任何操作,并将消息发送回代理到合适的队列.因此,要实现上面的场景,您的Python程序将检测图像是黑白还是彩色,并将(重新)发送到"黑白"或"颜色"队列,其中一些合适的客户将接管.
因此,在您的第二个问题上,您在客户端中执行任何基于内容的绑定都没有任何帮助.您的客户端如上所述工作,或者您在RabbitMQ本身中创建新的交换类型.然后,在客户端设置代码中,将交换类型定义为新类型.
希望这能回答你的问题!
在RabbitMQ中,路由是交换机决定将消息放在哪个队列的过程.您将所有消息发布到交换机,但您只接收来自队列的消息.这意味着交换是进程的活跃部分,它做出有关消息转发或复制的一些决定.
RabbitMQ中包含的主题交换查看传入消息(routing_key)上的字符串,并将其与所有队列提供的模式(binding_keys)相匹配,这些队列声明他们希望从交换机接收消息.
RabbitMQ源代码在网上,所以你可以在这里查看主题交换代码:http: //hg.rabbitmq.com/rabbitmq-server/file/9b22dde04c9f/src/rabbit_exchange_type_topic.erl 有很多复杂性处理称为trie的数据结构,允许非常快速的查找.实际上,在Internet路由器中使用相同的数据结构.
这里的标题交换http://hg.rabbitmq.com/rabbitmq-server/file/9b22dde04c9f/src/rabbit_exchange_type_headers.erl 可能更容易理解.正如您所看到的,进行不同类型的交换不需要很多代码.如果你想检查内容(或者只是查看消息的前几个字节,你应该能够快速识别XML与JSON相比其他东西.如果你的JSON对象和XML文档保持特定的元素序列,那么你应该能够在不解析整个消息体的情况下区分不同的JSON对象(或XML doc类型).