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-server

windows上安装:

(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的更多相关文章

  1. python3 访问 rabbitmq 示例

    关于 rabbitmq 之前用过 kafka,要是拿这两者做对比的话,大概有以下异同: 两者都是一个分布式架构 kafka 具有较高的吞吐量,rabbimq 吞吐量较小 rabbitmq 的可靠性更好 ...

  2. 循序渐进Python3(十)-- 0 -- RabbitMQ

    RabbitMQ     RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息 ...

  3. Python3.7.1学习(六)RabbitMQ在Windows环境下的安装

    Windows下安装RabbitMQ 环境配置 部署环境 部署环境:windows server 2008 r2 enterprise(本文安装环境Win7) 官方安装部署文档:http://www. ...

  4. RabbitMQ操作

    注意:在rabbitmq中,可以存在多个exchange,exchange只是负责接收消息,然后消息必须发送到给queue中,如果没有queue,消息就丢失了,exchange就相当于交换机,不负责存 ...

  5. Day11-协程/异步IO/RabbitMQ

    协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候 ...

  6. python之 rabbitmq

    一.发布hello world 首先我们看一个最简单的消息队列系统 #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ ...

  7. python rabbitmq

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ @author: zengchunyun ""& ...

  8. Python之路-python(rabbitmq、redis)

    一.RabbitMQ队列 安装python rabbitMQ module pip install pika or easy_install pika or 源码 https://pypi.pytho ...

  9. 19.python笔记之Rabbitmq

    RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消息队列(MQ)是一种应用程序 ...

随机推荐

  1. JavaScript之命名空间模式

    前言 命名空间可以被认为是唯一标识符下代码的逻辑分组.为什么会出现命名空间这一概念呢?因为可用的单词数太少,并且不同的人写的程序不可能所有的变量都没有重名现象.在JavaScript中,命名空间可以帮 ...

  2. iOS网络请求安全认证(JWT,RSA)

    在网络世界中,安全是一个很重要的问题,以往的HTTP请求已经不能承担这个安全任务,抓包工具一抓,你的所有网络请求全都曝光.当然,你可能会采用加密算法来加密数据,但是这仍然不够. 在移动端和服务器的通信 ...

  3. 牛客OI赛制测试赛-序列-模拟

    哇这道题好坑啊,可能是我太菜了 题意就是叫把一个连续序列分成K组,使得每个组的和都相等 我最开始的想法是由于要分成K组,那我们知道,每组一定有sum(a[i])/k这样我们只需要每次当num==sum ...

  4. 20135337——Linux实践三:程序破解

    程序破解 查看 运行 反汇编,查看汇编码 对反汇编代码进行分析: 在main函数的汇编代码中可以看出程序在调用"scanf"函数请求输入之后,对 [esp+0x1c] 和 [esp ...

  5. hover设定触发时间间隔

    500毫秒执行一次 $(".banner_menu_content li a").hover(function(){ var aa=$(this).text().trim(); s ...

  6. UML类图及类与类之间的关系

    原文地址:http://www.uml.org.cn/oobject/201211231.asp 类图用于描述系统中所包含的类以及它们之间的相互关系,帮助人们简化对系统的理解,它是系统分析和设计阶段的 ...

  7. b总结

    Beta 答辩总结 评审表 组名 格式 内容 ppt 演讲 答辩 总计 天机组 15 15 13 15 14 72 PMS 16 16 15 16 16 79 日不落战队 16 17 17 17 17 ...

  8. HDU 2021 发工资咯:)

    http://acm.hdu.edu.cn/showproblem.php?pid=2021 Problem Description 作为杭电的老师,最盼望的日子就是每月的8号了,因为这一天是发工资的 ...

  9. TortoiseSvn/Git的WaterEffect

    https://github.com/TortoiseGit/TortoiseGit/blob/master/src/Utils/MiscUI/WaterEffect.cpp C#的实现: http: ...

  10. python之datetime类

    datetime.time时间类,一般用于显示当地时间 import datetime # 新建对象 datetime_obj = datetime.time(hour=12, minute=20, ...