1. RabbitMQ介绍
本文所有客户端全部是基于Python,根据官网可以看出,Python有好几个扩展包可以使用:
RabbitMQ是一个消息代理。它的核心原理非常简单:接收和发送消息。RabbitMQ将发送消息和接收消息进行解耦,由此来实现应用程序的异步处理。如果将RabbitMQ视为一个服务,从大方向来看,RabbitMQ做了三件事情:
1. 收取请求
2. 存储请求信息
3. 分发请求
引用官网原文,你可以把它想像成一个邮局:你把信件放入邮箱,邮递员就会把信件投递到你的收件人处。在这个比喻中,RabbitMQ就扮演着邮箱、邮局以及邮递员的角色。
2. 名词解释
生产(Prouducing)意思就是发送,发送消息的应用程序就是一个(Prouducer),一般用“P”表示。队列(Queue),生产者将消息发送给RabbitMQ,是指发送给RabbitMQ的一个队列。多个生产者可以同时给一个队列发送消息,同时多个消费者也可以同时从队列取消息。消费者(Consuming)就是接收消息。一个消费者(Consumer)就是一个等待接收消息的应用程序
3. Hello World
Hello World实现一个最简单的程序,即一个生产者发送一条消息到RabbitMQ的队列,然后消费者读取消息并输出到屏幕上。基本逻辑是生产者(producer)把消息发送到一个名为“hello”的队列中。消费者(consumer)从这个队列中获取消息。RabbitMQ使用的是AMQP协议。要使用她你就必须需要一个使用同样协议的库。python可以从以下几个库中选择,我们这里选择的是pika,和官网的例子是一致的。使用Python自带工具pip进行安装,如何安装pip,可参考我的另外一篇如何搭建Python环境。安装pika[tRabbitMQ@iZ250x18mnzZ ~]$ pip install pika==0.95 Downloading/unpacking pika==0.95
发送消息程序
前面提到的生产者,也就是发送消息程序,分为以下几步处理:1. 创建连接RabbitMQ服务2. 建立通道3. 创建队列4. 发送消息5. 关闭连接整合代码如下:#!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2016-02-28 21:28:17 # @Author : mx (mx472756841@gmail.com) # @Link : http://www.shujutiyu.com/ # @Version : $Id$ import os import pika conn = None try: # 获取连接 conn = pika.BlockingConnection(pika.ConnectionParameters('localhost')) # 获取通道 channel = conn.channel() # 在发送队列前,需要确定队列是否存在,如果不存在RabbitMQ将会丢弃,先创建队列 channel.queue_declare('hello') # 在RabbitMQ中发送消息,不是直接发送队列,而是发送交换机(exchange),此处不多做研究,后面系列逐渐深入 ret = channel.basic_publish(exchange='', routing_key='hello', body="Hello, World!") print " [x] Sent 'Hello World!'" print ret except Exception, e: raise e finally: if conn: conn.close()
接收消息程序
前面提到的消费者,也就是接收消息程序,分为以下几步处理:
1. 创建连接2. 建立通道3. 创建队列(为防止队列不存在,队列存在也不会重新创建)4. 接收消息(接收消息需要一个回调函数)5. 启动程序,轮询等待消息整合代码如下:注:关于回调函数的参数,后面用到的时候再逐个解析。#!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2016-02-29 16:30:21 # @Author : mx (mx472756841@gmail.com) # @Link : http://www.shujutiyu.com/ # @Version : $Id$ import os import pika conn = None def callback(ch, method, properties, body): """ out body """ print " [x] Recived ch {0}".format(ch) print " [x] Recived method {0}".format(method) print " [x] Recived properties {0}".format(properties) print " [x] Recived %r" % (body, ) try: # get connection conn = pika.BlockingConnection(pika.ConnectionParameters( 'localhost') ) # get channel channel = conn.channel() # declare queue, 重复声明不会报错,但是没有队列的话直接取用会报错 channel.queue_declare('hello') # get message channel.basic_consume(callback, queue='hello', no_ack=True) print ' [*] Waiting for messages. To exit press CTRL+C' channel.start_consuming() except Exception, e: raise e finally: if conn: conn.close()
运行发送消息程序运行接收消息程序[tRabbitMQ@iZ250x18mnzZ src]$ python send_helloworld.py [x] Sent 'Hello World!' True
运行程序启动后,一直在等待获取消息,可以通过Ctrl-C来中止。Hello World基本就结束了,基本知道RabbitMQ基本的使用方法,后续将会进一步对RabbitMQ的使用场景进行解析。[tRabbitMQ@iZ250x18mnzZ src]$ python recv_helloworld.py [*] Waiting for messages. To exit press CTRL+C [x] Recived ch <pika.adapters.blocking_connection.BlockingChannel object at 0x7f61ecc6fa90> [x] Recived method <Basic.Deliver(['consumer_tag=ctag1.6c2c709930904468b40d0e1a758f7aca', 'delivery_tag=1', 'exchange=', 'redelivered=False', 'routing_key=hello'])> [x] Recived properties <BasicProperties> [x] Recived 'Hello, World!'