Rabbitmq 学习笔记(二)队列

队列

队列(queue)就是在生产者和消费者之间传递消息的对象:
具有以下特性:
- 同一个队列可以有多个生产者和多个消费者;
- 队列的创建具有幂等性,同一个名称的队列只会创建一次;
- 队列中的消息只会被其中一个消费者读取并处理,也就是说接收完之后就会被删除;
- 多个消费者轮流读取队列中的消息;
- 如果没有消费者,消息会保存在队列中;

代码演示,普通队列

演示环境介绍:centos 7, python 2.7, 使用rabbitmq的python版client库,pika。
想运行示例代码,需要事先安装rabbitmq和python环境。后面不再复述。

1.receiver.py 消费者

#!/usr/bin/env python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))             #我的环境中rabbitmq和示例代码在同一台服务器
channel = connection.channel()

channel.queue_declare(queue='hello')   #创建队列

def callback(ch, method, properties, body):     #消费者接受消息后处理回调函数
    print(" [x] Received %r" % body)

channel.basic_consume(callback,
                      queue='hello',
                      no_ack=True)             #接收消息函数参数定义

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

1.sender.py 生产者

#!/usr/bin/env python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='hello')

channel.basic_publish(exchange='',
                      routing_key='hello',
                      body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()

当没有消费者时,消息会保留在队列中。
图片1

消费者上线后,会读取队列中的消息。
图片2

提问: 如果队列中有没有被读取的消息时,rabbitmq服务重启,消息会丢吗?
答案:消息会丢失。
重启rabbitmq服务

代码演示,消息可靠性,防饿死机制

场景1: 如果消费者在接收消息过程中,出现意外终止的情况(网络不通、进程被杀死等),
队列中的消息会丢失,怎么处理?
消息可靠性通过 `no_ack` 参数设置: 
    true:表示不管消费者是否接收完整消息,都会丢失消息。
    false:需要等消息确认消息接收完整,才会删除队列中的消息缓存。
    默认值:false

场景2: 默认情况下,消费者会预读取队列中所有已经存在的消息,新加入的消费者会读取不到队列中这些消息。
也就是新加入的消费者被饿死了。怎么处理?
防饿死机制通过 basic_qos(prefetch_count=3) 函数设置预读取消息数量。

场景3:队列可靠性
durable=True 机制 ,持久化队列,重启服务也不会丢失

2.sender.py 生产者

#!/usr/bin/env python
import pika
import sys

connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='task_queue', durable=True)

message = ' '.join(sys.argv[1:]) or "Hello World!"
channel.basic_publish(exchange='',
                      routing_key='task_queue',
                      body=message,
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # make message persistent
                      ))
print(" [x] Sent %r" % message)
connection.close()

2.receiver.py 消费者

#!/usr/bin/env python
import pika
import time

connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='task_queue', durable=True)
print(' [*] Waiting for messages. To exit press CTRL+C')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)
    time.sleep(body.count(b'.'))      #让每条消息的接收时间变长一些,方便测试
    print(" [x] Done")
    ch.basic_ack(delivery_tag = method.delivery_tag)  #告诉队列接收消息完成

channel.basic_qos(prefetch_count=3)   #预读取3条消息
channel.basic_consume(callback,
                      queue='task_queue')

channel.start_consuming()

消费者接收完消息之后,打印done,再接收下一条消息。
第一个消费者预读取3条消息,第二个消费者从第4条消息开始接收。
后面消息轮流读取。
防饿死机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值