使用 RabbitMQ 和 Python 进行基于内容的路由
问题描述
是否可以使用 RabbitMQ 和 Python 进行基于内容的路由?
Is it possible with RabbitMQ and Python to do content-based routing?
AMQP 标准和 RabbitMQ 声称支持基于内容的路由,但是是否有任何 Python 库支持指定基于内容的绑定等?
The AMQP standard and RabbitMQ claims to support content-based routing, but are there any libraries for Python which support specifying content-based bindings etc.?
我目前使用的库(py-amqplib http://barryp.org/software/py-amqplib/) 似乎只支持带有简单模式匹配(#、*)的基于主题的路由.
The library I am currently using (py-amqplib http://barryp.org/software/py-amqplib/) seems to only support topic-based routing with simple pattern-matching (#, *).
解决方案
答案是是",但还有更多... :)
The answer is "yes", but there's more to it... :)
让我们首先就基于内容的路由的含义达成一致.有两种可能的意思.有人说它是基于消息的 header 部分.其他人说它基于消息的 data 部分.
Let's first agree on what content-based routing means. There are two possible meanings. Some people say that it is based on the header portion of a message. Others say it's based on the data portion of a message.
如果我们采用第一个定义,这些或多或少是我们所做的假设:数据在某处存在,并通过某个软件发送到 AMQP 代理.我们假设这个软件对数据有足够的了解,可以将键值 (KV) 对放在描述内容的消息的 header 中.理想情况下,发送者也是数据的生产者,因此它拥有我们想要的尽可能多的信息.假设数据是图像.然后我们可以让发送方将 KV 对放在消息头中,如下所示:
If we take the first definition, these are more or less the assumptions we make: The data comes into existence somewhere, and it gets sent to the AMQP broker by some piece of software. We assume that this piece of software knows enough about the data to put key-value (KV) pairs in the header of the message that describe the content. Ideally, the sender is also the producer of the data, so it has as much information as we could ever want. Let's say the data is an image. We could then have the sender put KV pairs in the message header like this:
width=1024
height=768
mode=bw
photographer=John Doe
现在我们可以通过创建适当的队列来实现基于内容的路由.假设我们对黑白图像执行单独的操作,对彩色图像执行单独的操作.我们可以创建两个队列,一个使用 mode=bw
接收消息,另一个使用 mode=colour
接收消息.然后我们有单独的客户端监听这些队列.代理执行路由,在我们的客户端中没有任何东西需要知道路由.
Now we can implement content-based routing by creating appropriate queues. Let's say we have a separate operation to perform on black-and-white images and a separate one on colour images. We can create two queues, one that receives messages with mode=bw
and another with mode=colour
. Then we have separate clients listening on those queues. The broker performs the routing, and there is nothing in our client that needs to be aware of the routing.
如果我们采用第二个定义,我们会从不同的假设出发.我们假设数据存在于某个地方,并通过某个软件发送到 AMQP 代理.但我们认为要求该软件使用 KV 对填充标头是不明智的.相反,我们希望根据 数据 本身做出路由决策.
If we take the second definition, we go from different assumptions. We assume that the data comes into existence somewhere, and it gets sent to AMQP broker by some piece of software. But we assume that it's not sensible to demand that that software should populate the header with KV pairs. Instead, we want to make a routing decision based on the data itself.
在 AMQP 中有两个选项:您可以决定为您的特定数据格式实现新的交换,或者您可以将路由委托给客户端.
There are two options for this in AMQP: you can decide to implement a new exchange for your particular data format, or you can delegate the routing to a client.
在RabbitMQ中,有direct(1-to-1)、fanout(1-to-N)、headers(header-filtered 1-to-N)和topic(topic-filtered 1-to-N)交换,但您可以根据 AMQP 标准实现自己的.这需要阅读大量 RabbitMQ 文档并在 Erlang 中实现交换.
In RabbitMQ, there are direct (1-to-1), fanout (1-to-N), headers (header-filtered 1-to-N) and topic (topic-filtered 1-to-N) exchanges, but you can implement your own according to the AMQP standard. This would require reading a lot of RabbitMQ documentation and implementing the exchange in Erlang.
另一种选择是在 Python 中创建一个 AMQP 客户端,以侦听一个特殊的内容路由队列".每当消息到达队列时,您的路由器客户端就会将其拾取,做任何需要做出路由决定的事情,然后将消息发送回代理到合适的队列.因此,为了实现上述场景,您的 Python 程序将检测图像是黑白还是彩色,并将(重新)发送到黑白"或彩色"队列,其中一些合适的客户会接手.
The other option is to make an AMQP client in Python that listens to a special "content routing queue". Whenever a message arrives at the queue, your router-client picks it up, does whatever is needed to make a routing decision, and sends the message back to the broker to a suitable queue. So to implement the scenario above, your Python program would detect whether an image is in black-and-white or colour, and would (re)send it to a "black-and-white" or a "colour" queue, where some suitable client would take over.
所以关于您的第二个问题,您在客户端中确实没有做任何基于内容的绑定.您的客户端可以如上所述工作,或者您在 RabbitMQ 本身中创建新的交换类型.然后,在您的客户端设置代码中,您将交换类型定义为您的新类型.
So on your second question, there's really nothing that you do in your client that does any content-based binding. Either your client(s) work as described above, or you create a new exchange type in RabbitMQ itself. Then, in your client setup code, you define the exchange type to be your new type.
希望这能回答你的问题!
Hope this answers your question!
相关文章