使用 RabbitMQ 和 Python 进行基于内容的路由

发布于 2024-09-10 10:29:48 字数 278 浏览 13 评论 0原文

是否可以使用 RabbitMQ 和 Python 进行基于内容的路由?

AMQP 标准和 RabbitMQ 声称支持基于内容的路由,但是 Python 是否有任何库支持指定基于内容的绑定等?

我当前正在使用的库(py-amqplib http://barryp.org/software/py-amqplib/ )似乎只支持具有简单模式匹配(#,*)的基于主题的路由。

Is it possible with RabbitMQ and Python to do content-based routing?

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.?

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 (#, *).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

£冰雨忧蓝° 2024-09-17 10:29:48

答案是“是”,但还有更多内容......:)

让我们首先就基于内容的路由的含义达成一致。有两种可能的含义。有人说它基于消息的标头部分。其他人则说它基于消息的数据部分。

如果我们采用第一个定义,这些或多或少是我们所做的假设:
数据在某个地方存在,并通过某种软件发送到 AMQP 代理。我们假设该软件对数据有足够的了解,可以将键值 (KV) 对放入描述内容的消息的标头中。理想情况下,发送者也是数据的生产者,因此它拥有我们想要的尽可能多的信息。假设数据是图像。然后,我们可以让发送者将 KV 对放入消息标头中,如下所示:

width=1024
height=768
mode=bw
photographer=John Doe

现在我们可以通过创建适当的队列来实现基于内容的路由。假设我们对黑白图像执行单独的操作,对彩色图像执行单独的操作。我们可以创建两个队列,一个使用 mode=bw 接收消息,另一个使用 mode=colour 接收消息。然后我们有单独的客户端监听这些队列。代理执行路由,我们的客户端中没有任何内容需要了解路由。

如果我们采用第二个定义,我们就会得出不同的假设。我们假设数据在某个地方存在,并通过某种软件发送到 AMQP 代理。但我们假设要求该软件用 KV 对填充标头是不明智的。相反,我们希望根据数据本身做出路由决策。

AMQP 中有两个选项:您可以决定为您的特定数据格式实现新的交换,或者您可以将路由委托给客户端。

在RabbitMQ中,有直接(1对1)、扇出(1对N)、标头(标头过滤的1对N)和主题(主题过滤的1对N)交换,但是你可以根据AMQP标准实现自己的。这需要阅读大量 RabbitMQ 文档并在 Erlang 中实现交换。

另一种选择是用 Python 创建一个 AMQP 客户端来监听特殊的“内容路由队列”。每当消息到达队列时,路由器客户端都会拾取它,执行做出路由决策所需的任何操作,并将消息发送回代理到合适的队列。因此,为了实现上述场景,您的 Python 程序将检测图像是黑白还是彩色,并将其(重新)发送到“黑白”或“彩色”队列,其中一些队列合适的客户将接手。

因此,关于第二个问题,您在客户端中实际上没有执行任何基于内容的绑定。您的客户端按照上述方式工作,或者您在 RabbitMQ 本身中创建新的交换类型。然后,在客户端设置代码中,将交换类型定义为新类型。

希望这能回答您的问题!

The answer is "yes", but there's more to it... :)

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.

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

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.

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.

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.

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.

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.

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!

坏尐絯℡ 2024-09-17 10:29:48

在 RabbitMQ 中,路由是交换器决定将消息放置到哪个队列的过程。您将所有消息发布到交换器,但仅从队列接收消息。这意味着交换是做出有关消息转发或复制的一些决策的过程的活跃部分。

RabbitMQ 包含的主题交换器查看传入消息上的字符串(routing_key),并将其与所有声明希望从交换器接收消息的队列提供的模式(绑定_keys)进行匹配。

RabbitMQ 源代码位于网络上,因此您可以在此处查看主题交换代码:
http://hg.rabbitmq.com/rabbitmq-server/file /9b22dde04c9f/src/rabbit_exchange_type_topic.erl
处理称为 trie 的数据结构非常复杂,它允许非常快速的查找。事实上,互联网路由器内部也使用相同的数据结构。

此处找到的标头交换 http://hg.rabbitmq.com/ rabbitmq-server/file/9b22dde04c9f/src/rabbit_exchange_type_headers.erl
可能更容易理解。正如您所看到的,进行不同类型的交换不需要太多代码。如果您想检查内容(或者只是查看消息的前几个字节,您应该能够快速识别 XML、JSON 和其他内容。如果您的 JSON 对象和 XML 文档维护特定的元素序列,那么您可以应该能够区分不同的 JSON 对象(或 XML 文档类型),而无需解析整个消息正文。

In RabbitMQ, routing is the process by which an exchange decides which queues to place your message on. You publish all messages to an exchange, but you only receive messages from a queue. This means that the exchange is an active part of the process that makes some decisions about message forwarding or copying.

The topic exchange included with RabbitMQ looks at a string on the incoming messages (the routing_key) and matches that with the patterns (the binding_keys) supplied by all queues which declare their desire to receive messages from the exchange.

RabbitMQ source code is on the web so you can have a look at the topic exchange code here:
http://hg.rabbitmq.com/rabbitmq-server/file/9b22dde04c9f/src/rabbit_exchange_type_topic.erl
A lot of the complexity there is to handle a data structure called a trie which allows for very fast lookups. In fact the same data structure is used inside Internet routers.

The headers exchange found here http://hg.rabbitmq.com/rabbitmq-server/file/9b22dde04c9f/src/rabbit_exchange_type_headers.erl
is probably easier to understand. As you can see there is not a lot of code required to make a different type of exchange. If you wanted to examine the content (or maybe just peek at the first few bytes of messages, you should be able to quickly identify XML versus JSON versus something else. And if your JSON objects and XML documents maintain a specific sequence of elements then you should be able to distinguish between different JSON objects (or XML doc types) without parsing the entire message body.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文