华子的代码空间

逆水行舟,不进则退。 关注系统编程、网络编程、并发、分布式。

RabbitMQ手册翻译 - Hello World的例子

Hello World

介绍:
RabbitMQ 是一个消息经纪人。它主要的目的很简单:接受并且发送消息。
你可以想到一个邮局:当你把一封邮件放到发信箱的时候,你确定邮差先生最终会把信件送达到收件人。
把RabbitMQ比喻为发信箱、邮局和邮差。

RabbitMQ和邮局的主要区别是,RabbitMQ接受消息,存储并且转发二进制数据(消息),而不是用纸张。

 

RabbitMQ中使用一些概念:

1. 生产者 只是发送消息。一个发送消息的程序是一个生产者,用P来表示它。

 

2. 队列 就像信箱一样。它位于RabbitMQ的内部。虽然消息流经过RabbitMQ和你的程序,但是他们只能被存储在队列中。
一个队列没有任何限制,它可以存储任何数据,只要你乐意。它实质上是无限大小的缓存。
多个生产者可以发送消息到一个队列中,多个消费者也可以从一个队列接收消息。

 

3. 消费 就是接收的意思。一个消费者程序主要是等待并且接收数据。用C来表示它。

 

Hello World!
(使用pika 0.95 python client)

我们的hello world不会很复杂,让我们发送一个消息,接收并且在屏幕上打印它。要实现这个,我们需要两种程序:一个发送消息,
另一个收到并且打印消息。

我们的设计大体上看起来是这样:

 

生产者发送消息到"hello"队列。消费者从队列接收消息。


RabbitMQ的库
RabbitMQ使用AMQP协议。要使用RabbitMQ你需要一个库,这个库理解协议本身并且也理解RabbitMQ。
在pyhon的世界里,有一打可用的库去选择:

py-amqplib
txAMQP
pika

在此系列的教程中,我们使用pika。要安装它你可以使用pip包管理工具:

$ sudo pip install pika=0.9.5

上面的命令依赖pip和git-core这两个包,你可能需要首先安装它们。

 

在Ubuntu上:

$ sudo apt-get install python-pip git-core

 

在Debian上:

$ sudo apt-get install python-setuptools git-core
$ sudo easy_install pip

 

在Windows上:要安装easy_install,使用Windows Installer安装setuptools。

> easy_install pip
> pip install pika==0.9.5

 

发送


我们的程序send.py会发送一个消息到队列中。但首先要做的是建立到RabbitMQ服务器的连接。

1 #!/usr/bin/env python
2 import pika
3 
4 connection = pika.BlockingConnection(pika.ConnectionParameters(
5                'localhost'))
6 channel = connection.channel()

 

  

现在已经建立了到localhost的连接。如果想连接到其他机器,我们只需要指定主机名或者IP地址。
接下来, 在准备发送之前需要确定接收的队列是否存在。如果我们发送消息到一个不存在的位置,
RabbitMQ只会丢弃消息(言下之意,它不会抛出错误)。
所以建立一个接收消息的队列,它叫hello。

1 channel.queue_declare(queue='hello')

 

现在我们可以发送消息了。我们的第一个消息只包含了一个字符串"hello rabbit",然后我们要把它发送到 hello 队列中。

在RabbitMQ中,你永远不能把消息直接发送到一个队列中,除非通过一个交换机(exchange)。
但是现在不要被繁琐的细节所拖累,你可以在第三个说明中阅读到关于交换机的细节信息。
我们现在只需要知道怎样用一个空字符串,定义一个交换机并使用它。
这个空字符串定义的交换机很特殊,它允许指定消息将要发送到哪个队列中。
队列的名字需要在routing_key中指定。

1 channel.basic_publish(exchange='',
2                       routing_key='hello',
3                       body='Hello World!')
4 print " [x] Sent 'Hello World!'"

 

在退出程序之前,我们需要确定缓存已经被flush,而且消息已经达到RabbitMQ。
我们可以以温柔的方式关闭连接,这样就能达到上面的目的:

1 connection.close()

 

 

 

接收:

第二个程序receive.py会从队列中接收消息,并打印消息到屏幕上。

再次重申,我们首先要连接到RabbitMQ服务器。负责连接的代码,在前面已经提到过,这里不再重复。

下一步需要确保队列已经存在,就像前面提到的一样。使用queue_declare创建一个队列是正确的,我们可以多次运行
它,但是最终只会创建一个队列。

1 channel.queue_declare(queue='hello'

你可能会问,已经在之前的代码中创建过了,为什么要再次创建队列。因为我们可以确保队列已经存在。
举例来说,我们在前面运行了send.py,但是我们不确定哪个程序是首先启动的。
在这种情况下,好的习惯就是在两个程序中都重复一次创建队列的动作。

 

列出存在的队列:

你也许想要知道,RabbitMQ中存在多少队列,每个队列中又存在多少消息。
可以使用rabbitmqctl这个命令(在特权用户下):

1 $ sudo rabbitmqctl list_queues
2 Listing queues ...
3 hello    0
4 ...done.

 

(在windows中没有sudo)

 

从队列中接收消息,就有一点复杂了。通过给队列指定一个回调函数,就可以做到。
当接收到一个消息,Pika就会调用回调函数。在我们的例子中,这个回调函数打印消息中的内容到屏幕上。

1 def callback(ch, method, properties, body):
2     print " [x] Received %r" % (body,)

接下来,我们需要告诉RabbitMQ这个回调函数需要从hello队列中接收消息:

1 channel.basic_consume(callback,
2                       queue='hello',
3                       no_ack=True)

想要让上面的代码运行成功,必须确保队列已经存在。幸运的是,我们有信心做到,
因为已经在前面使用queue_declare创建了一个队列。

no_ack这个参数会在稍后解释。

最后,我们让程序进入到一个无限循环中,等到数据的到来并运行回调函数。

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

 

 

放在一起来看:

send.py完整的代码:

 1 #!/usr/bin/env python
 2 import pika
 3 
 4 connection = pika.BlockingConnection(pika.ConnectionParameters(
 5         host='localhost'))
 6 channel = connection.channel()
 7 
 8 channel.queue_declare(queue='hello')
 9 
10 channel.basic_publish(exchange='',
11                       routing_key='hello',
12                       body='Hello World!')
13 print " [x] Sent 'Hello World!'"
14 connection.close(

 

 

receive.py完整的代码:

 1 #!/usr/bin/env python
 2 import pika
 3 
 4 connection = pika.BlockingConnection(pika.ConnectionParameters(
 5         host='localhost'))
 6 channel = connection.channel()
 7 
 8 channel.queue_declare(queue='hello')
 9 
10 print ' [*] Waiting for messages. To exit press CTRL+C'
11 
12 def callback(ch, method, properties, body):
13     print " [x] Received %r" % (body,)
14 
15 channel.basic_consume(callback,
16                       queue='hello',
17                       no_ack=True)
18 
19 channel.start_consuming()

 

 

现在我们可以在控制台运行程序了。首先用send.py发送一个消息:

1  $ python send.py
2  [x] Sent 'Hello World!'

生产者程序send.py会在每次运行之后退出。让我们来接收消息:

1 $ python receive.py
2  [*] Waiting for messages. To exit press CTRL+C
3  [x] Received 'Hello World!'

 

太棒了! 我们使用RabbitMQ发送了第一个消息。
你也许注意到了,receive.py程序没有退出,它持续接收后面到来的消息。当然可以用Ctrl-C退出程序。

我们学习了怎样使用一个命名的队列发送和接收消息,现在是时候学习如何创建一个简单的任务队列了。

 

posted on 2012-08-16 11:01  华子的代码空间  阅读(1504)  评论(0编辑  收藏  举报

导航