一、RabbitMQ介绍
RabbitMQ是一个消息代理。核心原理:接收和发送消息。RabbitMQ将发送消息和接收消息进行解耦,由此来实现应用程序的异步处
理。如果将RabbitMQ视为一个服务,从大方向来看,RabbitMQ做了三件事情:
1. 收取请求 存储 交换 路由
2. 存储请求信息
3. 分发请求
引用官网原文,你可以把它想像成一个邮局:你把信件放入邮箱,邮递员就会把信件投递到你的收件人处。在这个比喻中,
RabbitMQ服务器就扮演着邮箱、邮局以及邮递员的角色。
一般提到RabbitMQ和消息,都会用到一些专有名词。
队列(queue)就是邮箱的名称。消息通过你的应用程序和RabbitMQ进行传输,它们能够只存储在一个队列(queue)中。 队列(queue)没有任何限制,你要存储多少消息都可以——基本上是一个无限的缓冲。多个生产者(producers)能够把消息发送给同一个队列,同样,多个消费者(consumers)也能够从同一个队列(queue)中获取数据。队列可以绘制成这样(图上是队列的名称):
消费(Consuming)和获取消息是一样的意思。一个消费者(consumer)就是一个等待获取消息的程序。我们把它绘制为"C":
需要指出的是生产者、消费者、消息代理不需要 待在同一个设备上;事实上大多数应用也确实不在会将他们放在一台机器上。
二、Hello World!实例程序
1、程序的目的
“Hello world”不会很复杂——仅仅发送一个消息,然后获取它并输出到屏幕。这样以来我们需要两个程序,一个用作发送消
息,另一个接受消息并打印消息内容。
程序大致设计:
生产者(producer)把消息发送到一个名为"hello"的队列中。消费者(consumer)从队列中获取消息。
2、安装需要的python三方库
RabbitMQ使用的是AMQP协议。python可以从以下几个库中选择:py-amqplib txAMQP pika
ubuntu平台安装: 先来安装下rabbitmq,安装好后rabbitmq服务就已经启动好了。
sudo apt-get install rabbitmq-server
python使用rabbitmq服务,可以使用现成的类库pika、txAMQP或者py-amqplib,这里选择了pika。
安装pika:安装pika可以使用pip来进行安装,pip是python的软件管理包
sudo apt-get install python-pip
sudo pip install pika
3、发送消息
生产者:发送消息的程序。分为一下几步处理:
(1)、创建连接RabbitMQ服务器和创建通道
(2)、创建队列
(3)、发送消息
(4)、关闭连接
(1)、建立一个到RabbitMQ服务器的连接
#!/usr/bin/python
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
(2)、连接上服务器之后,发送消息之前应该确认队列是否存在。 发送消息到一个不存在的队列,RabbitMQ会丢弃这条消息。
先创建一个名为hello的队列,然后把消息发送到这个队列中。
channel.queue_declare(queue='hello')
这个时候就可以发送消息了,第一条消息只包含Hello World字符串,发送到我们的队列中。
(3)、RabbitMQ中,消息不能直接发送到队列,需要发送到交换机(exchange 后面会详细讨论)中。 现在我们需要了解的是如何使用
默认交换机,使用空字符来标识。
交换机允许我们指定某条消息需要投递到哪个队列,routing_key必须指定为队列的名称:
channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')
print " [x] Sent 'Hello World!'"
(4)、退出程序之前,我们需要确认
网络缓冲已经被刷写、消息已经投递到RabbitMQ服务器的队列中。完成之后正确的关闭连接:
connection.close()
#!/usr/bin/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()
4、获取数据
消费者,也就是接收消息程序,分为以下几步处理:
(1) 创建连接建立通道
(2) 创建队列(为防止队列不存在,队列存在也不会重新创建)
(3) 接收消息(接收消息需要一个回调函数)
(4) 启动程序,轮询等待消息
(1)、连接到RabbitMQ服务器,创建通道。
(2)、确认队列是否存在。使用queue_declare创建一个队列----可以运行这个命令很多次,但是只有一个队列被创建。
channel.queue_declare(queue='hello')
疑问:为什么重复声明队列呢?如果我们确定队列已经存在,那么可以不这么做,比如此前预先运行send.py程序。可是我们并不确
定哪个程序会首先运行。重复队列声明值得推荐的做法。
列出所有对类的命令:查看RabbitMQ中有哪些队列、有多少消息在队列中
rabbitmqctl list_queues
(3)、为队列定义回调(callback)函数。当我们获取到消息的时候,pika库就会调用此回调函数。回调函数负责将接收到的消息内
容输出到屏幕上。
def callback(ch, method, properties, body):
print " [x] Received %s" % (body,)
(4)、我们需要 告诉RabbitMQ
回调函数将会从名为"hello"的队列中接收消息:
channel.basic_consume(callback, queue='hello', no_ack=True)
成功的运行这些命令,必须保证队列是存在的。 no_ack参数稍后会进行介绍。
(5)、等待消息数据并且在需要的时候运行回调函数的无限循环:
print ' [*] Waiting for messages. To exit press CTRL+C'
channel.start_consuming()
#!/usr/bin/python
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello')
print ' [*] Waiting for messages. To exit press CTRL+C'
def callback(ch, method, properties, body):
print " [x] Received %s" % (body,)
channel.basic_consume(callback, queue='hello', no_ack=True)
channel.start_consuming()
注:关于回调函数的参数,后面用到再一一解析。
三、运行程序
运行发送消息程序:生产者
运行接收消息程序:消费者
运行程序启动后,一直在等待获取消息,可以通过Ctrl-C来中止。Hello World基本就结束了,基本知道RabbitMQ基本的使用方法。
现在我们已经学会如何发送消息到一个已知队列中并接收消息。 下一部分我们将会建立一个简单的工作队列。
参考资料: