RabbitMQ(part2轮流发消息到不同消费者)----Work Queues

来源:互联网 发布:Mac怎么安装压缩文件 编辑:程序博客网 时间:2024/06/05 15:55

官方稳定链接:

一、https://www.rabbitmq.com/tutorials/tutorial-two-python.html

1、new_task.py代码:

import pikaimport sysconnection=pika.BlockingConnection(pika.ConnectionParameters('localhost',5672));channel=connection.channel();channel.queue_declare(queue='task_queue');message=' '.join(sys.argv[1:]) or "Hello World!";channel.basic_publish(exchange='',routing_key='task_queue',body=message,properties=pika.BasicProperties(delivery_mode=2,))print("[x] sent %r "%message);connection.close();

worker.py代码:

import pikaimport timeconnection=pika.BlockingConnection(pika.ConnectionParameters('localhost'));channel=connection.channel();channel.queue_declare(queue='task_queue');def callback(ch,method,properties,body):    print(ch,method,properties);    print("[x] Received %r "%body);    time.sleep(body.count(b'.'));    print("[x] done");channel.basic_consume(callback,queue='task_queue');print("[x] Waiting for message.To exit press CTRL+C");channel.start_consuming();
2、运行结果:

疑问:为什么new_task生产者发送消息。并且有个消费者worker也消费了一个,但在队列中消息不标记为删除呐?依然显示有一个消息。

二、

当在C1和C2同时运行时,假如两者现在都处于在等待新消息的状态(已经接收过几条消息了。),突然终止某个消费者,发现,另一个消费者会重新接收终止消费者之前所接收的所有已处理的消息(还处理么?反正很快就显示done了。。目测,再处理一遍)。

当某C消费者没执行完某条消息就被终止时,另一个消费者会从头接收被终止的消费者之前接收的所有消息,直到未执行完的消息执行完了。

注意,此时,用rabbitmqctl list_queues发现消息队列里的消息就是曾经发过的消息条数。(为什么没减呐?


三、

实验总结:

ch.basic_ack(delivery_tag = method.delivery_tag)
作用:

将上面worker.py中callback函数最后一行添加此语句。


实验结果:


看见某条消息是否执行完毕,看见done才可。所以上面没有处理完接收的消息。


注意:此时,在终止C1消费者程序时,C2消费者只接收C1没处理完的消息。以上处理完的消息将不再接收和处理。并且此时用命令rabbitmqctl list_queues查看消息队列中的消息条数时,显示为0条,即代表都已经处理完?

总结:以上一、二、三、在Rabbitmq重启后,消息队列均会消失。不具有持久性。

四、

RabbitMQ崩溃后不影响我们的消息队列,和里面的消息应该怎么做?

代码如下:

new_task.py

import pikaimport sysconnection=pika.BlockingConnection(pika.ConnectionParameters('localhost',5672));channel=connection.channel();channel.queue_declare(queue='task_queue2',durable=True);#never lose our queuemessage=' '.join(sys.argv[1:]) or "Hello World!";channel.basic_publish(exchange='',routing_key='task_queue2',body=message,properties=pika.BasicProperties(delivery_mode=2,))#mark our messages as persistent print("[x] sent %r "%message);connection.close();

worker.py:

import pikaimport timeconnection=pika.BlockingConnection(pika.ConnectionParameters('localhost'));channel=connection.channel();channel.queue_declare(queue='task_queue2',durable=True);def callback(ch,method,properties,body):    print(ch,method,properties);    print("[x] Received %r "%body);    time.sleep(body.count(b'.'));    print("[x] done");    ch.basic_ack(delivery_tag=method.delivery_tag);channel.basic_consume(callback,queue='task_queue2');print("[x] Waiting for message.To exit press CTRL+C");channel.start_consuming();

测试:


在服务器重启后,队列task_queue2具有持久性。而此时队列task_queue已经消失了。

注意:Marking messages as persistent doesn't fully guarantee that a message won't be lost.  If you need a stronger guarantee then you can use publisher confirms.

五、

new_task1.py:

import pikaimport sysconnection=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,));print("[x] sent %r "%message);connection.close();

work1.py:

import pikaimport timeconnection=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(prfetch_count=1);#控制每个消费者一次接收的消息条数,只有返回ack,才会接收发送者的另一条消息channel.basic_consume(callback,queue='task_queue');channel.start_consuming();


阅读全文
0 0
原创粉丝点击