python3之rabbitMQ
1、RabbitMQ介绍
RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现。AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有很多公开标准(如 COBAR的 IIOP ,或者是 SOAP 等),但是在异步消息处理中却不是这样,只有大企业有一些商业实现(如微软的 MSMQ ,IBM 的 Websphere MQ 等),因此,在 2006 年的 6 月,Cisco 、Redhat、iMatix 等联合制定了 AMQP 的公开标准。
MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消 息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。
消息队列技术是分布式应用间交换信息的一种技术;消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走;通过消息队列,应用程序可独立地执行--它们不需要知道彼此的位置、或在继续执行前不需要等待接收程序接收此消息。
MQ主要作用是接受和转发消息。你可以想想在生活中的一种场景:当你把信件的投进邮筒,邮递员肯定最终会将信件送给收件人。我们可以把MQ比作 邮局和邮递员。
MQ和邮局的主要区别是,它不处理消息,但是,它会接受数据、存储消息数据、转发消息。
2、安装RabbitMQ
linux上安装:
安装配置epel源
$ rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm 安装erlang $ yum -y install erlang安装RabbitMQ $ yum -y install rabbitmq-serverwindows上安装:
(1)首先,您需要安装支持的 Windows 版Erlang。运行Erlang Windows安装程序。Erlang将出现在开始菜单中,设置erlang的环境变量(C:\erl9.2\bin;),测试erlang是否安装正确:cmd-输入:erl,能看到eshell版本号,说明安装成功!
(2)下载rabbitMQ:(安装下一步完成即可)
https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.3/rabbitmq-server-windows-3.7.3.zip
(3)安装RabbitMQ-Plugins,这个相当于是一个管理界面,方便我们在浏览器界面查看RabbitMQ各个消息队列以及交换的工作情况,安装方法是:打开命令行cd进入rabbitmq的sbin目录(我的目录是:C:\ software \ rabbitmq \ rabbitmq_server-3.6.5 \ sbin),输入:rabbitmq-plugins enable rabbitmq_management命令,稍等会会发现出现plugins安装成功的提示,默认是安装6个插件。
插件安装完之后,在浏览器输入的http://本地主机:15672进行验证
如果不能打开页面解决方法:首先在命令行输入:rabbitmq-service stop,接着输入rabbitmq-service remove,再接着输入rabbitmq-service install,接着输入rabbitmq-service start,最后重新输入rabbitmq-plugins enable rabbitmq_management试试,我是这样解决的。
创建用户名,密码,绑定角色:
RabbitMQ报错解决方法:
C:\RabbitMQ Server\rabbitmq_server-3.7.\sbin>rabbitmqctl.bat status
Status of node rabbit@DESKTOP-6JT7D2H ...
Error: unable to perform an operation on node 'rabbit@DESKTOP-6JT7D2H'. Please see diagnostics information and suggestions below. Most common reasons for this are: * Target node is unreachable (e.g. due to hostname resolution, TCP connection or firewall issues)
* CLI tool fails to authenticate with the server (e.g. due to CLI tool's Erlang cookie not matching that of the server)
* Target node is not running In addition to the diagnostics info below: * See the CLI, clustering and networking guides on http://rabbitmq.com/documentation.html to learn more
* Consult server logs on node rabbit@DESKTOP-6JT7D2H DIAGNOSTICS
=========== attempted to contact: ['rabbit@DESKTOP-6JT7D2H'] rabbit@DESKTOP-6JT7D2H:
* connected to epmd (port ) on DESKTOP-6JT7D2H
* epmd reports node 'rabbit' uses port for inter-node and CLI tool traffic
* TCP connection succeeded but Erlang distribution failed * Authentication failed (rejected by the remote node), please check the Erlang cookie Current node details:
* node name: 'rabbitmqcli57@DESKTOP-6JT7D2H'
* effective user's home directory: C:\Users\Administrator.DESKTOP-6JT7D2H
* Erlang cookie hash: RmzKErjVZUcsMU8wSgBGbA== 解决方法:
将C:\Users\tracyclock\.erlang.cookie 文件拷贝到C:\Windows\System32\config\systemprofile替换掉.erlang.cookie文件
重启rabbitMQ服务:net stop RabbitMQ && net start RabbitMQ
查看用户及用户角色:rabbitmqctl.bat list_users
C:\RabbitMQ Server\rabbitmq_server-3.7.\sbin>rabbitmqctl.bat list_users
Listing users ...
guest [administrator]
新增用户:rabbitmqctl.bat add_user username password
C:\RabbitMQ Server\rabbitmq_server-3.7.\sbin>rabbitmqctl.bat add_user admin
Adding user "admin" ... C:\RabbitMQ Server\rabbitmq_server-3.7.\sbin>rabbitmqctl.bat list_users
Listing users ...
admin []
guest [administrator]
用户角色:
rabbitmq用户角色可分为五类:超级管理员, 监控者, 策略制定者, 普通管理者以及其他。
(1) 超级管理员(administrator)
可登陆管理控制台(启用management plugin的情况下),可查看所有的信息,并且可以对用户,策略(policy)进行操作。
(2) 监控者(monitoring)
可登陆管理控制台(启用management plugin的情况下),同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
(3) 策略制定者(policymaker)
可登陆管理控制台(启用management plugin的情况下), 同时可以对policy进行管理。
(4) 普通管理者(management)
仅可登陆管理控制台(启用management plugin的情况下),无法看到节点信息,也无法对策略进行管理。
(5) 其他的
无法登陆管理控制台,通常就是普通的生产者和消费者。
授权用户为超级管理员:rabbitmqctl.bat set_user_tags admin administrator
C:\RabbitMQ Server\rabbitmq_server-3.7.\sbin>rabbitmqctl.bat set_user_tags admin administrator
Setting tags for user "admin" to [administrator] ... C:\RabbitMQ Server\rabbitmq_server-3.7.\sbin>rabbitmqctl.bat list_users
Listing users ...
admin [administrator]
guest [administrator]
用户可以设置多个角色:rabbitmqctl.bat set_user_tags username tag1 tag2 ...
修改用户密码:rabbitmqctl change_password userName newPassword
C:\RabbitMQ Server\rabbitmq_server-3.7.\sbin>rabbitmqctl.bat change_password admin
Changing password for user "admin" ...
删掉用户:rabbitmqctl.bat delete_user username
C:\RabbitMQ Server\rabbitmq_server-3.7.\sbin>rabbitmqctl.bat delete_user guest
Deleting user "guest" ... C:\RabbitMQ Server\rabbitmq_server-3.7.\sbin>rabbitmqctl.bat list_users
Listing users ...
admin [administrator]
权限相关命令为:
(1) 设置用户权限
rabbitmqctl set_permissions -p VHostPath User ConfP WriteP ReadP
(2) 查看(指定hostpath)所有用户的权限信息
rabbitmqctl list_permissions [-p VHostPath]
(3) 查看指定用户的权限信息
rabbitmqctl list_user_permissions User
(4) 清除用户的权限信息
rabbitmqctl clear_permissions [-p VHostPath] User
3、python3使用pika python客户端
发出消息(生产者):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/2/22 15:51
# @Author : Py.qi
# @File : rabbitMQ_send_1.py
# @Software: PyCharm import pika,sys
print('send....start....')
while True:
inputso=input('soinsideto:')
if inputso == 'quit':
break
#与RabbitMQ服务器建立链接
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
#建立隧道
channel = connection.channel()
#创建队列名称zhang
channel.queue_declare(queue='zhang')
#发送信息:exchange指定交换,routing_key指定队列名,body指定消息内容
channel.basic_publish(exchange='',routing_key='zhang',body=inputso)
#关闭链接
connection.close()
接收者(消费者):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/2/22 15:57
# @Author : Py.qi
# @File : rabbitMQ_rescv_1.py
# @Software: PyCharm import pika
#创建链接
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
#建立隧道
channel = connection.channel()
#创建队列名,此处也可省略,在找不到队列时创建
channel.queue_declare(queue='zhang')
#使用回调函数callback来接收消息并打印消息
def callback(ch,method,properties,body):
print('recived:',body)
#指定队列接收消息,callback接收消息,queue指定队列,no_ack不给发送者发送确认消息
channel.basic_consume(callback,queue='zhang',no_ack=True)
print('waiting for message,to exit press ctrl+c')
#持续接收消息,阻塞
channel.start_consuming()
默认情况下,RabbitMQ会按顺序将每条消息发送到下一个使用者,每个消费者按顺序获得同样数量的消息,这种分配方式称为循环法。
(1)消息持久化:
当RabbitMQ退出或者崩溃时,它会忘记队列和消息,需要做两件事来确保消息不会丢失:我们需要将队列和消息标记为持久化。
在创建队列时指定durable为True来标记队列持久化:
channel.queue_declare(queue='hehe',durable=True)
将消息标记为持久化,通过提供值为2的delivery_mode属性
channel.basic_publish(exchange='',
routing_key='hehe',
body=inputso,
properties=pika.BasicProperties(
delivery_mode=2, # make message persistent
))
(2)消息公平分发
如果RabbitMQ只管按顺序把消息发送到每个消费者上,不考虑消费者的负载,很可能出现一个机器配置不高的消费者那里堆积很多消息处理不完,同时配置高的机器却很轻松。为了解决这个问题,可以在每个消费者端,配置perfetch=1,意识就是告诉RabbitMQ在我这个消费者当前消息还没处理完的时候就不要再发新消息了。

为了解决这个问题,我们可以使用basic.qos方法和 prefetch_count = 1设置。这告诉RabbitMQ一次不要向工作人员发送多于一条消息。或者换句话说,不要向工作人员发送新消息,直到它处理并确认了前一个消息。相反,它会将其分派给不是仍然忙碌的下一个工作人员。
channel.basic_qos(prefetch_count = 1)
完整代码:
生产者:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/2/22 15:51
# @Author : Py.qi
# @File : rabbitMQ_send_1.py
# @Software: PyCharm import pika
print('send....start....')
while True:
inputso=input('soinsideto:')
if inputso == 'quit':
break
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.146.129'))
channel = connection.channel()
channel.queue_declare(queue='hehe',durable=True)
channel.basic_publish(exchange='',
routing_key='hehe',
body=inputso,
properties=pika.BasicProperties(
delivery_mode=2, # make message persistent
))
connection.close()
消费者:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/2/22 15:57
# @Author : Py.qi
# @File : rabbitMQ_rescv_1.py
# @Software: PyCharm import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.146.129'))
channel = connection.channel()
channel.queue_declare(queue='hehe',durable=True)
def callback(ch,method,properties,body):
print('recived:',body)
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_qos(prefetch_count=1) #确认发送消息个数
channel.basic_consume(callback,queue='hehe',no_ack=True)
print('waiting for message,to exit press ctrl+c')
channel.start_consuming()
(3)消息发布与订阅
发布订阅和简单的消息队列区别在于,发布订阅会将消息发送给所有的订阅者,而消息队列中的数据被消费一次便消失。所以,RabbitMQ实现发布和订阅时,会为每一个订阅者创建一个队列,而发布者发布消息时,会将消息放置在所有相关队列中。
发布消息类似于广播效果,需要用到exchange,在定义exchange时指定类型来决定哪些queue符合条件,可以接收消息:
有几种可用的交换类型:direct, topic, headers 和fanout。我们将关注最后一个fanout。我们创建该类型的交换,并将其称为logs:
channel.exchange_declare(exchange='logs',
exchange_type='fanout')
fanout:所有bind到此exchange的queue都可以接收到消息
direct:通过routingKey和exchange决定的哪个唯一的queue可以接收消息
topic:所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息。
表达式符号:#代表一个或多个字符,*代表任何字符
fanout交换,它只是将收到的所有消息广播到它所知道的所有队列中。
要列出服务器上的交换,可以使用命令rabbitmqctl:
sudo rabbitmqctl list_exchanges
广播消息,fanout实例:
生产者:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/2/24 17:05
# @Author : Py.qi
# @File : rabbit_send_fanout.py
# @Software: PyCharm
import pika
import sys
connection=pika.BlockingConnection(pika.ConnectionParameters(host='192.168.146.129'))
channel=connection.channel()
#指定交换类型
channel.exchange_declare(exchange='logs',exchange_type='fanout')
#message = ' '.join(sys.argv[1:]) or 'info:hello world!'
for i in range(10):
channel.basic_publish(exchange='logs',routing_key='',body=str(i))
print('[x]sent %r'%i)
connection.close()
消费者:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/2/24 17:12
# @Author : Py.qi
# @File : rabbit_recv_fanout.py
# @Software: PyCharm import pika connection = pika.BlockingConnection(pika.ConnectionParameters(
host='192.168.146.129'))
channel = connection.channel()
#指定交换类型
channel.exchange_declare(exchange='logs',
exchange_type='fanout')
#让服务器随机生成队列名,一旦消费者链接关闭,队列将被删除
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
#将队列绑定到交换上
channel.queue_bind(exchange='logs',
queue=queue_name)
print(' [*] Waiting for logs. To exit press CTRL+C') def callback(ch, method, properties, body):
print(" [x] %r" % body) channel.basic_consume(callback,
queue=queue_name,
no_ack=True)
channel.start_consuming()
接收消息时指定队列, exchange type = direct
RabbitMQ还支持根据关键字发送,即:队列绑定关键字,发送者将数据根据关键字发送到消息exchange,exchange根据关键字判断应该将数据发送至指定队列。
生产者:发布消息
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/2/26 9:25
# @Author : Py.qi
# @File : rabbit_send_direct.py
# @Software: PyCharm import pika
import sys conn = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.146.129'))
channel = conn.channel()
#绑定exchange类型为指定接收
channel.exchange_declare(exchange='direct_logs',exchange_type='direct')
#判断参数个数
severity=sys.argv[1] if len(sys.argv) > 1 else 'info'
#发送消息
message = ' '.join(sys.argv[2:]) or 'hello world'
#消息发送到exchange交换队列
channel.basic_publish(exchange='direct_logs',routing_key=severity,body=message)
print('[x]sent %r:%r'%(severity,message))
conn.close()
消费者:接收消息
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/2/26 9:54
# @Author : Py.qi
# @File : rabbit_recver_direct.py
# @Software: PyCharm import pika,sys
conn = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.146.129'))
channel = conn.channel()
channel.exchange_declare(exchange='direct_logs',exchange_type='direct')
#随机队列名,结束即删除
result = channel.queue_declare(exclusive=True)
queue_name=result.method.queue
#接收队列消息关键参数
severities=sys.argv[1:]
if not severities:
sys.stderr.write('Usage:%s[info][warning][error]\n'%sys.argv[0])
sys.exit(1)
#循环将消息发送到有关键字队列中
for severity in severities:
channel.queue_bind(exchange='direct_logs',
queue=queue_name,
routing_key=severity)
print('[*]waiting for logs,To exit press CTRL+C')
def callback(ch,method,properites,body):
print('[x]%r:%r'%(method.routing_key,body))
channel.basic_consume(callback,
queue=queue_name,
no_ack=True)
channel.start_consuming()
模糊匹配:
exchange type = topic
在topic类型下,可以让队列绑定几个模糊的关键字,之后发送者将数据发送到exchange,exchange将传入”路由值“和 ”关键字“进行匹配,匹配成功,则将数据发送到指定队列。
#:表示可以匹配0个或多个单词
*:表示只能匹配一个单词
生产者:发送消息
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/2/26 10:42
# @Author : Py.qi
# @File : rabbit_send_topic.py
# @Software: PyCharm import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='192.168.146.129'))
channel = connection.channel()
#指定exchange为模糊匹配topic
channel.exchange_declare(exchange='topic_logs',
exchange_type='topic') routing_key = sys.argv[1] if len(sys.argv) > 1 else 'anonymous.info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='topic_logs',
routing_key=routing_key,
body=message)
print(" [x] Sent %r:%r" % (routing_key, message))
connection.close()
消费者:接收消息
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/2/26 10:43
# @Author : Py.qi
# @File : rabbit_recve_topic.py
# @Software: PyCharm
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='192.168.146.129'))
channel = connection.channel()
#exchange模式topic
channel.exchange_declare(exchange='topic_logs',
exchange_type='topic') result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue binding_keys = sys.argv[1:]
if not binding_keys:
sys.stderr.write("Usage: %s [binding_key]...\n" % sys.argv[0])
sys.exit(1) for binding_key in binding_keys:
channel.queue_bind(exchange='topic_logs',
queue=queue_name,
routing_key=binding_key) print(' [*] Waiting for logs. To exit press CTRL+C') def callback(ch, method, properties, body):
print(" [x] %r:%r" % (method.routing_key, body)) channel.basic_consume(callback,
queue=queue_name,
no_ack=True) channel.start_consuming()

python3之rabbitMQ的更多相关文章
- python3 访问 rabbitmq 示例
关于 rabbitmq 之前用过 kafka,要是拿这两者做对比的话,大概有以下异同: 两者都是一个分布式架构 kafka 具有较高的吞吐量,rabbimq 吞吐量较小 rabbitmq 的可靠性更好 ...
- 循序渐进Python3(十)-- 0 -- RabbitMQ
RabbitMQ RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息 ...
- Python3.7.1学习(六)RabbitMQ在Windows环境下的安装
Windows下安装RabbitMQ 环境配置 部署环境 部署环境:windows server 2008 r2 enterprise(本文安装环境Win7) 官方安装部署文档:http://www. ...
- RabbitMQ操作
注意:在rabbitmq中,可以存在多个exchange,exchange只是负责接收消息,然后消息必须发送到给queue中,如果没有queue,消息就丢失了,exchange就相当于交换机,不负责存 ...
- Day11-协程/异步IO/RabbitMQ
协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候 ...
- python之 rabbitmq
一.发布hello world 首先我们看一个最简单的消息队列系统 #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ ...
- python rabbitmq
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ @author: zengchunyun ""& ...
- Python之路-python(rabbitmq、redis)
一.RabbitMQ队列 安装python rabbitMQ module pip install pika or easy_install pika or 源码 https://pypi.pytho ...
- 19.python笔记之Rabbitmq
RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消息队列(MQ)是一种应用程序 ...
随机推荐
- 理解Liang-Barsky裁剪算法的算法原理
0.补充知识向量点积:结果等于0, 两向量垂直; 结果大于0, 两向量夹角小于90度; 结果小于0, 两向量夹角大于90度.直线的参数方程:(x1, y1)和(x2, y2)两点确定的直线, 其参数方 ...
- 一个高性能的对象属性复制类,支持不同类型对象间复制,支持Nullable<T>类型属性
由于在实际应用中,需要对大量的对象属性进行复制,原来的方法是通过反射实现,在量大了以后,反射的性能问题就凸显出来了,必须用Emit来实现. 搜了一圈代码,没发现适合的,要么只能在相同类型对象间复制,要 ...
- Mycat读写分离、主从切换、分库分表的操作记录
系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...
- GlusterFS分布式存储数据的恢复机制(AFR)的说明
GlusterFSFS恢复数据都是基于副本卷来说的,GlusterFSFS复制卷是采用镜像的方式做的,并且是同步事务性操作.简单来说就是,某一个客户要写文件时,先把这个文件锁住,然后同时写两个或多个副 ...
- 【Beta阶段】第九次Scrum Meeting!(论坛已成功上线)
每日任务内容: 本次会议为第九次Scrum Meeting会议~ 本次会议为团队项目第九次会议,在会议前大家取得了重大成果! 队员 昨日完成任务 明日要完成任务 刘乾 #179 完成1021的数据处理 ...
- Java实验二
北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1351 姓名:黄君如 学号:20135117 成绩: 指导教师:娄 ...
- Linux内核分析-系统中断在内核中的实现
分析system_call中断处理过程 在MenuOS中添加上周所运用到的系统调用 即在Linuxkernel/menu/test.c文件中,添加代码如下: int Mkdir() { const c ...
- <构建之法>13-17
13章软件测试. 从基本名词到软件测试的分类方法,啃完这15页书,至少对与软件测试的理解程度不是停留在以前的层次(让用户使用,然后提出碰到什么问题) 测试不是那么简单就阐述的完全.测试按测试目的分类可 ...
- 数学战神app(小学生四则运算app)开发需求及进度
项目名字:“数学战神” 开发环境:Android eclipse 团队名称:战神联盟 团队成员:陈思明,许家豪,王宏财,吴旭涛 在之前的四则运算APP中添加更多的实用功能,并在各种平台推广宣传. 预加 ...
- java中for循环的几种方式
比如定义一个数组int a[]={1, 2, 3, 4},下面我们罗列一下遍历这个数组的方法 1 for(;;) 这也是最常用的方法,不多做解释.代码如下 int a[] = {1, 2, 3, 4} ...