消息要保持“持久化”,即不丢失,必须要使得消息、交换器、队列,必须全部 “持久化”。
1. 生产者怎么确认 RabbitMQ 已经收到了消息?
# 打开通道的确认模式
channel.confirm_delivery()
msg_props = pika.BasicProperties()
msg_props.content_type = 'text/plain'
message = "hello world"
# message = '{"a": 1, "b": 2}'
# basic_publish 中的 routing_key 叫做路由键
ack = channel.basic_publish(exchange='ex_2', routing_key='abc.123',
properties=msg_props, body=message)
if ack:
print "send msg successful"
else:
print "send msg failed"
2. RabbitMQ 怎么告知生产者消息已经到达队列呢?
# 打开通道的确认模式
channel.confirm_delivery()
msg_props = pika.BasicProperties()
msg_props.content_type = 'text/plain'
message = "hello world"
# message = '{"a": 1, "b": 2}'
# basic_publish 中的 routing_key 叫做路由键
ack = channel.basic_publish(
exchange='ex_2', routing_key='abc.123',
mandatory=True, properties=msg_props, body=message)
'''
当 mandatory 参数设置为 true 时,交换机无法根据自身的路由键找到一个符合的队列,
那么 RabbitMQ 会调用 Basic.Return 命令将消息返回给生产者,
当 mandatory 参数设置为 false 时,出现上述情况,消息会被丢弃。
'''
if ack:
print "send msg successful"
else:
print "send msg failed"
channel.close()
connect.close()
3. RabbitMQ 怎么确保消息被消费者消费呢?
在消费确认的场景下,RabbitMQ
给消费者发送消息,消费者接收消息后发送 Basic.Ack
给 RabbitMQ
进行消费确认。
4. RabbitMQ 又是如何保证消息不丢的呢?
RabbitMQ
主要是采用持久化的方式保证消息不丢,启用队列、交换机、消息的持久化,确保不会因为 RabbitMQ
服务器的宕机导致消息丢失。
# pika.BasicProperties(delivery_mode=2消息持久化
ack = channel.basic_publish(
exchange='ex_2', routing_key='abc.123',
mandatory=True,
properties=pika.BasicProperties(delivery_mode=2, ),
body=message
)
properties=pika.BasicProperties(delivery_mode=2, )
即可表示消息是要进行持久化的。
- 队列声明时持久化例子:
channel.queue_declare(queue='queue_3', durable=True)
- 交换机声明初始化;
channel.exchange_declare(
exchange='ex_2',
exchange_type='direct',
passive=False,
durable=True,
auto_delete=False
)
各个函数的详细参数含义请参考以下文章: