rabbitmq使用方法(二)
Work Queues

In the first tutorial we wrote programs to send and receive messages from a named queue. In this one we'll create a Work Queue that will be used to distribute time-consuming tasks among multiple workers.
The main idea behind Work Queues (aka: Task Queues) is to avoid doing a resource-intensive task immediately and having to wait for it to complete. Instead we schedule the task to be done later. We encapsulate a task as a message and send it to the queue. A worker process running in the background will pop the tasks and eventually execute the job. When you run many workers the tasks will be shared between them.
Round-robin dispatching
One of the advantages of using a Task Queue is the ability to easily parallelise work. If we are building up a backlog of work, we can just add more workers and that way, scale easily.
By default, RabbitMQ will send each message to the next consumer, in sequence. On average every consumer will get the same number of messages. This way of distributing messages is called round-robin.
Message acknowledgment
Doing a task can take a few seconds. You may wonder what happens if one of the consumers starts a long task and dies with it only partly done. With our current code once RabbitMQ delivers message to the customer it immediately removes it from memory. In this case, if you kill a worker we will lose the message it was just processing. We'll also lose all the messages that were dispatched to this particular worker but were not yet handled.
But we don't want to lose any tasks. If a worker dies, we'd like the task to be delivered to another worker.
In order to make sure a message is never lost, RabbitMQ supports message acknowledgments. An ack(nowledgement) is sent back from the consumer to tell RabbitMQ that a particular message had been received, processed and that RabbitMQ is free to delete it.
If consumer dies without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will redeliver it to another consumer. That way you can be sure that no message is lost, even if the workers occasionally die.
There aren't any message timeouts; RabbitMQ will redeliver the message only when the worker connection dies. It's fine even if processing a message takes a very, very long time.
Message durability
We have learned how to make sure that even if the consumer dies, the task isn't lost. But our tasks will still be lost if RabbitMQ server stops.
When RabbitMQ quits or crashes it will forget the queues and messages unless you tell it not to. Two things are required to make sure that messages aren't lost: we need to mark both the queue and messages as durable.
First, we need to make sure that RabbitMQ will never lose our queue. In order to do so, we need to declare it as durable:
channel.queue_declare(queue='hello', durable=True)
Although this command is correct by itself, it won't work in our setup. That's because we've already defined a queue called hello which is not durable. RabbitMQ doesn't allow you to redefine an existing queue with different parameters and will return an error to any program that tries to do that. But there is a quick workaround - let's declare a queue with different name
This queue_declare change needs to be applied to both the producer and consumer code.
At that point we're sure that the task_queue queue won't be lost even if RabbitMQ restarts. Now we need to mark our messages as persistent - by supplying a delivery_mode property with a value 2.
channel.basic_publish(exchange='',
routing_key="task_queue",
body=message,
properties=pika.BasicProperties(
delivery_mode = 2, # make message persistent
))
Fair dispatch
You might have noticed that the dispatching still doesn't work exactly as we want. For example in a situation with two workers, when all odd messages are heavy and even messages are light, one worker will be constantly busy and the other one will do hardly any work. Well, RabbitMQ doesn't know anything about that and will still dispatch messages evenly.
This happens because RabbitMQ just dispatches a message when the message enters the queue. It doesn't look at the number of unacknowledged messages for a consumer. It just blindly dispatches every n-th message to the n-th consumer.

In order to defeat that we can use the basic.qos method with the prefetch_count=1 setting. This tells RabbitMQ not to give more than one message to a worker at a time. Or, in other words, don't dispatch a new message to a worker until it has processed and acknowledged the previous one. Instead, it will dispatch it to the next worker that is not still busy.
channel.basic_qos(prefetch_count=1)
Putting it all together
Final code of our new_task.py script:
#!/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()
And our worker:(new_task.py source)
#!/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('.') )
print " [x] Done"
ch.basic_ack(delivery_tag = method.delivery_tag) channel.basic_qos(prefetch_count=1)
channel.basic_consume(callback,
queue='task_queue') channel.start_consuming()
rabbitmq使用方法(二)的更多相关文章
- RabbitMQ学习系列二-C#代码发送消息
RabbitMQ学习系列二:.net 环境下 C#代码使用 RabbitMQ 消息队列 http://www.80iter.com/blog/1437455520862503 上一篇已经讲了Rabbi ...
- RabbitMQ官方教程二 Work Queues(GOLANG语言实现)
RabbitMQ官方教程二 Work Queues(GOLANG语言实现) 在第一个教程中,我们编写了程序来发送和接收来自命名队列的消息. 在这一部分中,我们将创建一个工作队列,该队列将用于在多个wo ...
- RabbitMQ入门教程(二):简介和基本概念
原文:RabbitMQ入门教程(二):简介和基本概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn ...
- Android抓包方法(二)之Tcpdump命令+Wireshark
Android抓包方法(二) 之Tcpdump命令+Wireshark 前言 做前端测试,基本要求会抓包,会分析请求数据包,查看接口是否调用正确,数据返回是否正确,问题产生是定位根本原因等.学会抓包分 ...
- Java 简单实用方法二
整理以前的笔记,在学习Java时候,经常会用到一些方法.虽然简单但是经常使用.因此做成笔记,方便以后查阅 这篇博文先说明构造和使用这些方法. 1,判断String类型数据是否包含中文 可以通过正则表达 ...
- SSH框架的多表查询(方法二)增删查改
必须声明本文章==>http://www.cnblogs.com/zhu520/p/7773133.html 一:在前一个方法(http://www.cnblogs.com/zhu520/p ...
- RAC(ReactiveCocoa)使用方法(二)
RAC(ReactiveCocoa)使用方法(一) RAC(ReactiveCocoa)使用方法(二) 上篇文章:RAC(ReactiveCocoa)使用方法(一) 中主要介绍了一些RAC中常见类的用 ...
- Microsoft Edge浏览器下载文件乱码修复方法(二)
之前有写过"Microsoft Edge浏览器下载文件乱码修复方法",发现很多情况下下载文件乱码问题还是存在,这里对之前内容做简单补充,希望可以帮到大家. 方法二: 默认如果提示下 ...
- mybatis由浅入深day02_2一对一查询_2.3方法二:resultMap_resultType和resultMap实现一对一查询小结
2.3 方法二:resultMap 使用resultMap,定义专门的resultMap用于映射一对一查询结果. 2.3.1 sql语句 同resultType实现的sql SELECT orders ...
- Selenium应用代码(常见封装的方法二)
滚动窗口: //将滚动条滚到适合的位置 , 方法一 public static void setScroll(WebDriver driver,int height){ try { // String ...
随机推荐
- mysql系列八、mysql数据库优化、慢查询优化、执行计划分析
mysql的性能优化无法一蹴而就,必须一步一步慢慢来,从各个方面进行优化,最终性能就会有大的提升. 一.介绍 对mysql优化是一个综合性的技术,主要包括 表的设计合理化(符合3NF) 添加适当索引( ...
- 如何设置使eclipse修改代码不重启tomcat
tomcat配置 1.server.xml reloadable="true"<Context docBase="ins" path="/ins ...
- 利用jstack命令定位占用cpu高的java线程及具体错误代码信息
1.先用top查询某进程的线程CPU占用情况,定位到cpu占用高的进程pid 2.根据pid定位具体的线程top -p PID -H ,找出占用cpu最大的pid,此处占用cpu比较平均,我们随便选择 ...
- vmware下centos克隆功能对网络的设置
centos完成克隆功能后需要对网络进行设置 # cd /etc/udev/rules.d/ vim 70-persistent-net.rules 删除eth0的配置,将eth1该为eth0 编辑网 ...
- 转载:使用Nginx的必备软件(1.3.2)《深入理解Nginx》(陶辉)
原文:https://book.2cto.com/201304/19612.html 如果要使用Nginx的常用功能,那么首先需要确保该操作系统上至少安装了如下软件. (1)GCC编译器 GCC(GN ...
- 常用adb操作命令详解
1. 查看当前运行的所有设备adb devices 返回当前设备列表 这个命令是查看当前连接的设备, 连接到计算机的android设备或者模拟器将会列出显示2. 安装软件adb install验证是否 ...
- visual studio 2017 installer 安装包制作过程出现的问题---此安装程序需要.NET Framework 版本 3.5,请安装该版本,然后重新运行此安装程序,可以从Web获得.NET Framework 。要立即做此事吗?
图一 visual studio 2017 installer 打包完成以后进行安装时,提示信息 “安装此安装程序需要.NET Framework 版本 3.5,请安装该版本,然后重新运行此安装程序, ...
- Java EE 8 来了
作者 李士窑 发布于 2014年9月2日. 估计阅读时间: 不到一分钟 | 自2013年6月Java EE 7发布以来,Java开发团队在这段时间内一直在规划和搜集下一个大版本Java EE 8带 ...
- MACE(2)-----模型编译
作者:十岁的小男孩 QQ:929994365 无用 本文仅用于学习研究,非商业用途,欢迎大家指出错误一起学习,文章内容翻译自 MACE 官方手册,记录本人阅读与开发过程,力求不失原意,但推荐阅读原文. ...
- 《剑指offer》-孩子们的游戏(圆圈中最后剩下的数)
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指定一个数m ...