RabbitMQ的Python客户端pika使用调研

消息队列的作用

消息队列最早产生在金融领域,是为解决金融业务的IT系统中产生的一些问题而应运而生的。随着互联网和电子商务的发展,消息队列在不同行业、不同场景下得到了广泛运用。消息队列主要有能解决三个问题:

异步解耦

在分布式系统中,不同应用之间的相互调用,如果采用同步的方式,请求发起方发起调用之后,接收调用方需要在处理完成之后,再同步地返回执行结果给到调用方,在此过程请求发起方需要一直等待被调用方的反馈结果。这在处理时间较短的场景下,并没有什么问题。但是一旦处理时间过长的话,就会导致请求方程序一直阻塞,不能处理后续流程。故而需要引入一个中间人,就像一个邮筒,来收发信件,而不必发件人和收件人直接交换信息。消息队列就这样应运而生了,消息队列利用发布-订阅模式工作,消息发送者发布消息,一个或者多个消息接受者订阅消息。消息发送者是消息源,在对消息进行处理后将消息发送至分布式消息队列,消息接受者从非分布式消息队列获取该消息后继续进行处理。可以看到,消息发送者和消息接受者直接没有直接的耦合关系。

流量削峰填谷

无论在互联网还是传统行业中,IT系统的访问量、业务请求与时间的关系都不是均匀分布的。比如每年的“6.18”和“双十一”,或者12306的春运车票发售日,系统的请求都会迎来高峰。或者因为某些促销活动、热点事件,也会导致系统达到峰值。但是系统的没个应用程序的单个节点的处理能力是有限的,不能在短期内处理所有请求。这种问题其实在现实生活中也很常见,比如超市促销时,客流激增,商家会组织顾客排队购买、排队支付。其实消息队列,也可以看做这种排队的思想的引入。通过将大量请求放入消息队列,进行排队,让消费者挨个处理请求,而不超出消费者程序的承载上限,较好地削平了流量高峰,在请求量低的时候又把之前积压的请求继续处理。它就像一根可以稳定压力的,让水流均匀流动的水管,从而保证整个系统中的运转效率保持均匀稳定。

RPC(Remote Procedure Call)

RPC即所谓远程过程调用,前面将消息队列来实现异步解耦的时候已经说明,它可以做不同应用程序相互调用的“中间人”。但作RPC时就还必须考虑到,消费方接收到消息,并且处理完该消息包含的请求后,还必须有个应答的过程。所以,消息生产者(请求方)在消息头里必须指定该条消息的编号(correlation_id)和消费者(接收请求方)应答消息应该写入哪个队列(如图,reply_to信息),消息消费者在处理完之后,它又会转换成一个消息生产者的角色,向消息队列指定的队列中写入一调带correlation_id的应答消息。当RPC请求方接收到这条消息时,就知道编号correlation_id消息包含的调用已完成。


image

AMQP的几个概念

image.png

Product(生产者):

将消息的生产(发生)出来的程序

Consumer(消费者):

等待接收消息的程序

Broker(消息中间件):

将消息由生产者传递给消费者的中介软件,就是我们常说的消息中间件(MQ)。包括知名的RabbitMQ、RacketMQ、ZeroMQ、Kafka、Redis(NOSQL,也用作消息中间件)。

Virtual host(虚拟机):

考虑到多租户情境下的安全因素,对broker进行虚拟的资源划分,类似于VLAN。同一个消息中间件,可以划分出多个vhost,供不同用户在其中创建使用exchange和Queue,以保持数据的隔离性和安全性。

Channel(管道):

应用程序对broker的访问,必须先建立起连接,但是应用程序需要发送/接收大量消息,如果每次发生/接收消息的操作都去建立一次连接,那么对部署broker的机器资源的开销是巨大的。所以必须做到多次访问对一次连接的复用,这就需要应用程序用多线程的方式访问broker。同时还得对每一次消息收发,能保证数据的隔离性,那就必须由broker对消息传递的渠道做一定的分隔。channel就是为了实现这个目的而产生的,相当于在broker内部对一个connection做了切分,实现了多个轻量级的connection,以极大地节约系统开销。

Exchange (路由器)

负责分发消息的组件,相当于网络中的路由器。message进入broker首先由Exchange处理,根据分发规则,查询表中的routing key,来讲消息分发到对应的Queue中去。常用的分发规则有direct(point to point),topic(publish-subscribe)and fanout(mutilcast)。

Queue(队列)

消息队列,消息真正被写入和读取的地方,一个message可以拷贝到多个Queue上去。

Binding(路由规则)

exchange和queue之间的虚拟连接,binding中可以包含routing key。Binding信息被保存到exchange中的查询表中,用于message的分发依据。

Message(消息)

分为消息头和消息体,消息头主要记录供broker处理分发的信息,消息体才是真正被消费者需要的信息。

RabbitMQ的几大特性

RabbitMQ作为AMQP的一个实现,基本遵循了上述AMQP的一些机制。主要具备以下特性,篇幅考虑,这里只做简单列举,日后再详细叙述。
消息确认机制
队列持久化
消息持久化
消息的拒收

RabbitMQ的安装和配置

以CentOS 7 为例

安装
erlangy与rabbitMQ版本对照关系表

$sudo yum install erlang -y
$sudo yum install rabbitmq-server-3.7.4-1.el7.noarch.rpm
#开启管理后台插件(可选,默认端口15672)
$sudo rabbitmq-plugins enble rabbitmq_management
#启动
$sudo rabbitmq-server

配置

#创建管理员用户
$sudo rabbitmqctl add_user  user_admin  passwd_admin
#赋予其administrator角色
$sudo rabbitmqctl set_user_tags user_admin administrator
#创建RabbitMQ监控用户,负责整个MQ的监控
$sudo rabbitmqctl add_user  user_monitoring  passwd_monitor
#赋予其monitoring角色
$sudo rabbitmqctl set_user_tags user_monitoring monitoring
#创建某个项目的专用用户,只能访问项目自己的virtual hosts
$sudo rabbitmqctl  add_user  user_proj  passwd_proj
#查看所有用户
$sudo rabbitmqctl list_users

pika的使用

pika是RabbitMQ官方文档推荐的Python客户端,如果我们采用Python编写使用RabbitMQ的应用程序,我们最好应该采用pika来实现。

pika使用简单示例

生产者程序示例:sendmq.py

#!/usr/bin/env python
import pika

credentials = pika.PlainCredentials('czq', 'czq')
Parameter = pika.ConnectionParameters('127.0.0.1',5672,'/',credentials,heartbeat_interval=0)
connection = pika.BlockingConnection(Parameter)
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()

消费者程序示例:receviemq.py

import pika

credentials = pika.PlainCredentials('czq', 'czq')
Parameter = pika.ConnectionParameters('127.0.0.1',5672,'/',credentials,heartbeat_interval=0)
connection = pika.BlockingConnection(Parameter)
channel = connection.channel()


channel.queue_declare(queue='hello')

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

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

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

参考资料

[1]RabbitMQ官方文档:
http://www.rabbitmq.com/tutorials/tutorial-one-python.html
[2]pika官方文档:
http://pika.readthedocs.io/en/0.10.0/modules/channel.html
[3]RabbitMQ与AMQP协议详解
https://www.cnblogs.com/frankyou/p/5283539.html
[4]李智慧,《大型网站技术架构:核心原理与案例分析》,电子工业出版社,2013年9月1日
[5] RabbitMQ在线模拟学习
http://tryrabbitmq.com/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,701评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,649评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,037评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,994评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,018评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,796评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,481评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,370评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,868评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,014评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,153评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,832评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,494评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,039评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,437评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,131评论 2 356

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,673评论 18 139
  • http://liuxing.info/2017/06/30/Spring%20AMQP%E4%B8%AD%E6%...
    sherlock_6981阅读 15,925评论 2 11
  • 来源 RabbitMQ是用Erlang实现的一个高并发高可靠AMQP消息队列服务器。支持消息的持久化、事务、拥塞控...
    jiangmo阅读 10,365评论 2 34
  • 什么叫消息队列 消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂...
    lijun_m阅读 1,349评论 0 1
  • 本文大纲 RabbitMQ 历史 RabbitMQ 应用场景 RabbitMQ 系统架构 RabbitMQ 基本概...
    Java_Explorer阅读 16,390评论 1 40