RabbitMQ:具有主题交换的持久消息
我对兔子很陌生 我已经建立了一个“主题”交流。用户可以在发布者之后启动。我希望消费者能够接收在他们上线之前发送的消息,而这些消息还没有被消费 使用以下参数设置exchange:RabbitMQ:具有主题交换的持久消息,rabbitmq,amqp,Rabbitmq,Amqp,我对兔子很陌生 我已经建立了一个“主题”交流。用户可以在发布者之后启动。我希望消费者能够接收在他们上线之前发送的消息,而这些消息还没有被消费 使用以下参数设置exchange: exchange_type => 'topic' durable => 1 auto_delete => 0 passive => 0 使用此参数发布消息: delivery_mode => 2 使用者使用get()从exchange检索消息 不幸的是,在任何客户端启动之前发布的任何消息
exchange_type => 'topic'
durable => 1
auto_delete => 0
passive => 0
使用此参数发布消息:
delivery_mode => 2
使用者使用get()从exchange检索消息
不幸的是,在任何客户端启动之前发布的任何消息都将丢失。我使用了不同的组合
我想我的问题是交换不保存消息。也许我需要在发布者和消费者之间建立一个队列。但这似乎不适用于通过密钥路由消息的“主题”交换
我应该如何进行?我使用
Perl
绑定Net::RabbitMQ
(应该没关系)和RabbitMQ 2.2.0
如果在消息发布时没有可用的连接消费者来处理消息,则需要一个持久队列来存储消息
exchange不存储消息,但队列可以。令人困惑的是,交换可以标记为“持久”,但真正的意思是,如果重新启动代理,交换本身仍将存在,但这并不意味着发送到该交换的任何消息都会自动持久化
鉴于此,有两种选择:
队列是需要适当管理和控制的东西。否则,最终可能会有流氓消费者声明持久队列,使用它们几分钟,但再也不会使用。不久之后,您将拥有一个永久性增长的队列,而队列的大小却没有任何减少,并且即将出现代理灾难。正如Brian所提到的,exchange不存储消息,主要负责将消息路由到另一个exchange或队列。如果exchange未绑定到队列,则发送到该exchange的所有消息都将“丢失” 您不需要在发布服务器脚本中声明固定客户端队列,因为这可能是不可伸缩的。发布者可以动态创建队列,并使用exchange到exchange绑定在内部路由队列 RabbitMQ支持exchange到exchange绑定,这将允许拓扑灵活性、解耦和其他好处。你可以在这里阅读更多 示例Python代码,用于在不存在使用队列的使用者时创建具有持久性的exchange到exchange绑定
#/usr/bin/env python
进口鼠兔
导入系统
连接=pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel=connection.channel()
#声明所有生产者用于发送消息的条目交换。也可能是外部生产商
channel.exchange\u declare(exchange='data\u gateway',
交换\u type='fanout',
持久的,
自动删除(错误)
#声明要使用的处理交换。将消息路由到各种队列。仅供内部使用
channel.exchange\u declare(exchange='data\u distributor',
交换_type='topic',
持久的,
自动删除(错误)
#将面向外部/生产商的exchange绑定到内部exchange
channel.exchange\u bind(destination='data\u distributor',source='data\u gateway')
##创建绑定到数据分发服务器exchange的持久队列
channel.queue\u declare(queue='trade\u db',dustable=True)
channel.queue\u declare(queue='trade\u stream\u service',durable=True)
channel.queue\u declare(queue='ticker\u db',dustable=True)
channel.queue\u declare(queue='ticker\u stream\u service',durable=True)
channel.queue\u declare(queue='orderbook\u db',dustable=True)
channel.queue\u declare(queue='orderbook\u stream\u service',durable=True)
#将队列绑定到交换机并更正路由密钥。允许在没有消费者时保存消息
channel.queue\u绑定(queue='orderbook\u db',exchange='data\u distributor',routing\u key='*.*.orderbook')
channel.queue\u绑定(queue='orderbook\u stream\u service',exchange='data\u distributor',routing\u key='*.*.orderbook')
channel.queue\u bind(queue='ticker\u db',exchange='data\u distributor',routing\u key='*.*.ticker')
channel.queue\u bind(queue='ticker\u stream\u service',exchange='data\u distributor',routing\u key='*.*.ticker')
channel.queue\u bind(queue='trade\u db',exchange='data\u distributor',routing\u key='*.*.trade')
channel.queue\u bind(queue='trade\u stream\u service',exchange='data\u distributor',routing\u key='*.*.trade')
您的案例似乎是“消息持久性”。
从中,您需要将队列
和消息
标记为持久(下面的代码为C版本。对于其他语言,您可以更喜欢)
队列
在RabbitMQ
节点重新启动后仍然有效。为了做到这一点,我们需要宣布其为耐用:channel.QueueDeclare(queue: "hello",
durable: true,
....);
var properties = channel.CreateBasicProperties();
properties.Persistent = true;