消息队列之rabbitmq学习使用

1、RabbitMQ简介

1.1、什么是RabbitMQ?

RabbitMQ是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,RabbitMQ是使用Erlang语言来编写的,并且RabbitMQ是基于 AMQP协议的。

1.2、RabbitMQ有哪些特点?

  • 目前大多数互联网都在使用RabbitMQ

  • RabbitMQ底层采用Erlang语言进行编写

  • 开源、性能优秀,稳定

  • 与SpringAMQP完美的整合、API丰富,只要是你能想到的编程语言几乎都有与其相适配的RabbitMQ客户端。

  • 集群模式丰富,表达式配置,HA模式,镜像队列模型

  • 保证数据不丢失的前提做到高可靠、可用性

  • RabbitMQ附带了一个易于使用的可视化管理工具,它可以帮助你监控消息代理的每一个环节。

  • 如果你的消息系统有异常行为,RabbitMQ还提供了追踪的支持,让你能够发现问题所在。

  • RabbitMQ附带了各种各样的插件来对自己进行扩展。你甚至也可以写自己的插件来使用。

1.3、AMQP协议模型

2、RabbitMQ安装使用

2.1 安装rabbitmq,配置好阿里云的yum源,epel源
yum -y install erlang  rabbitmq-server
2.2 启动rabbitmq服务端
systemctl start rabbitmq-server
2.3 创建rabbitmq的后台管理用户
  • 创建用户 sudo rabbitmqctl add_user 账户 密码
[root@zfy2 ~]# rabbitmqctl add_user admin 000000
Creating user "admin" ...
...done.
  • 设置用户管理员身份 sudo rabbitmqctl set_user_tags 账户 administrator
[root@zfy2 ~]# rabbitmqctl set_user_tags admin administrator
Setting tags for user "admin" to [administrator] ...
...done.
  • 允许用户对所有的队列都可以读写 sudo rabbitmqctl set_permissions -p "/" xiaohu ".*" ".*" ".*"
[root@zfy2 ~]# rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
Setting permissions for user "admin" in vhost "/" ...
...done.
  • 重启服务端,让用户添加生效
systemctl restart rabbitmq-server
  • 开启web界面rabbitmq
rabbitmq-plugins enable rabbitmq_management
  • 访问web界面默认端口的 15672
http://192.168.16.193:15672/

2.4 下面是一些关于用户操作的命令
# 新建用户
rabbitmqctl add_user {用户名} {密码} # 设置权限
rabbitmqctl set_user_tags {用户名} {权限} # 查看用户列表
rabbitmqctl list_users # 为用户授权
# 添加 Virtual Hosts :
rabbitmqctl add_vhost <vhost> # 删除用户
rabbitmqctl delete_user Username # 修改用户的密码
rabbitmqctl change_password Username Newpassword # 删除 Virtual Hosts :
rabbitmqctl delete_vhost <vhost> # 添加 Users :
rabbitmqctl add_user <username> <password>
rabbitmqctl set_user_tags <username> <tag> ...
rabbitmqctl set_permissions [-p <vhost>] <user> <conf> <write> <read> # 删除 Users :
delete_user <username> # 使用户user1具有vhost1这个virtual host中所有资源的配置、写、读权限以便管理其中的资源
rabbitmqctl set_permissions -p vhost1 user1 '.*' '.*' '.*' # 查看权限
rabbitmqctl list_user_permissions user1
rabbitmqctl list_permissions -p vhost1 # 清除权限
rabbitmqctl clear_permissions [-p VHostPath] User # 清空队列步骤
rabbitmqctl reset
需要提前关闭应用 rabbitmqctl stop_app
然后再清空队列,启动应用
rabbitmqctl start_app
此时查看队列rabbitmqctl list_queues 查看所有的exchange: rabbitmqctl list_exchanges
查看所有的queue: rabbitmqctl list_queues
查看所有的用户: rabbitmqctl list_users
查看所有的绑定(exchange和queue的绑定信息): rabbitmqctl list_bindings
查看消息确认信息:
rabbitmqctl list_queues name messages_ready messages_unacknowledged
查看RabbitMQ状态,包括版本号等信息:rabbitmqctl status
2.5 安装pika模块
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple pika==0.11.1
2.6 创建一个py文件
[root@zfy2 rabbitmq]# touch send.py
[root@zfy2 rabbitmq]# touch Receive.py
2.7 通过python的pika模块,实现生产消费者
  • 生产者代码如下 send.py
#!/usr/bin/env python
import pika # 创建凭证,使用rabbitmq用户密码登录
credentials = pika.PlainCredentials("admin","000000") # 新建连接,这里localhost可以更换为服务器ip
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.193',credentials=credentials)) # 创建频道
channel = connection.channel() # 声明一个队列,用于接收消息,队列名字叫“西游记”
channel.queue_declare(queue='西游记') # 注意在rabbitmq中,消息想要发送给队列,必须经过交换(exchange),初学可以使用空字符串交换(exchange=''),它允许我们精确的指定发送给哪个队列(routing_key=''),参数body值发送的数据
channel.basic_publish(exchange='',
routing_key='西游记',
body='大师兄,师傅被妖怪抓走了')
print("已经发送了消息")
# 程序退出前,确保刷新网络缓冲以及消息发送给rabbitmq,需要关闭本次连接
connection.close()

执行代码:

[root@zfy2 rabbitmq]# python3 send.py
已经发送了消息

  • 运行消费者代码 Receive.py
import pika

# 建立与rabbitmq的连接
# 前四行都是连接到同一个rabbitmq服务端以及同一个队列
credentials = pika.PlainCredentials("admin","000000")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.193',credentials=credentials))
channel = connection.channel()
channel.queue_declare(queue="西游记") def callbak(ch,method,properties,body):
print("消费者取出了消息:%r"%body.decode("utf8")) # 有消息来临,立即执行callbak,没有消息则夯住,等待消息
channel.basic_consume(callbak,queue="西游记",no_ack=True) #no_ack 不用确认 # 开始消费,接收消息
channel.start_consuming()

执行代码:

[root@zfy2 rabbitmq]# python3 Receive.py
消费者取出了消息:'大师兄,师傅被妖怪抓走了'
2.8 消息应答之ack机制

为了确保消息不会丢失,RabbitMQ支持消息应答。消费者发送一个消息应答,告诉RabbitMQ这个消息已经接收并且处理完毕了。RabbitMQ就可以删除它了。

如果一个消费者挂掉却没有发送应答,RabbitMQ会理解为这个消息没有处理完全,然后交给另一个消费者去重新处理。这样,你就可以确认即使消费者偶尔挂掉也不会丢失任何消息了。

没有任何消息超时限制;只有当消费者挂掉时,RabbitMQ才会重新投递。即使处理一条消息会花费很长的时间。

消息应答是默认打开的。我们通过显示的设置autoAsk=true关闭这种机制。现即自动应答开,一旦我们完成任务,消费者会自动发送应答。通知RabbitMQ消息已被处理,可以从内存删除。如果消费者因宕机或链接失败等原因没有发送ACK(不同于ActiveMQ,在RabbitMQ里,消息没有过期的概念),则RabbitMQ会将消息重新发送给其他监听在队列的下一个消费者。

  • 生产者代码如下
#!/usr/bin/env python
import pika # 创建凭证,使用rabbitmq用户密码登录
credentials = pika.PlainCredentials("admin","000000") # 新建连接,这里localhost可以更换为服务器ip
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.193',credentials=credentials)) # 创建频道
channel = connection.channel() # 新建一个hello队列,用于接收消息
channel.queue_declare(queue='金品没') # 注意在rabbitmq中,消息想要发送给队列,必须经过交换(exchange),初学可以使用空字符串交换(exchange=''),它允许我们精确的指定发送给哪个队列(routing_key=''),参数body值发送的数据
channel.basic_publish(exchange='',
routing_key='金品没',
body='大郎,起来喝药了')
print("已经发送了消息")
# 程序退出前,确保刷新网络缓冲以及消息发送给rabbitmq,需要关闭本次连接
connection.close()

执行代码:

[root@zfy2 rabbitmq]# python3 send1.py
已经发送了消息

  • 消费者代码
import pika

credentials = pika.PlainCredentials("admin","000000")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.193',credentials=credentials))
channel = connection.channel() # 声明一个队列(创建一个队列)
channel.queue_declare(queue='金品没') def callback(ch, method, properties, body):
print("消费者接受到了任务: %r" % body.decode("utf-8")) # 让程序报错,没有给生成者一个消息应答
int('asdfasdf') # 我告诉rabbitmq服务端,我已经取走了消息
# 回复方式在这
ch.basic_ack(delivery_tag=method.delivery_tag) # 关闭no_ack,代表给与服务端ack回复,确认给与回复
channel.basic_consume(callback,queue='金品没',no_ack=False) #no_ack=False 禁止不确认机制,代表需要给与服务端消息确认回复
channel.start_consuming()

执行代码:

[root@zfy2 rabbitmq]# python3 Receive1.py
消费者接受到了任务: '大郎,起来喝药了'
Traceback (most recent call last):
File "Receive1.py", line 23, in <module>
channel.start_consuming()
File "/usr/local/lib/python3.6/site-packages/pika/adapters/blocking_connection.py", line 1780, in start_consuming
self.connection.process_data_events(time_limit=None)
File "/usr/local/lib/python3.6/site-packages/pika/adapters/blocking_connection.py", line 716, in process_data_events
self._dispatch_channel_events()
File "/usr/local/lib/python3.6/site-packages/pika/adapters/blocking_connection.py", line 518, in _dispatch_channel_events
impl_channel._get_cookie()._dispatch_events()
File "/usr/local/lib/python3.6/site-packages/pika/adapters/blocking_connection.py", line 1403, in _dispatch_events
evt.body)
File "Receive1.py", line 15, in callback
int('asdfasdf')
ValueError: invalid literal for int() with base 10: 'asdfasdf'

可以看出当消费者虽然已经接收到消息但是没有给生产者做消息应答时,数据任然不会丢失

2.9 让队列以及消息支持持久化,防止异常崩溃,消息丢失
  • 生产者代码,生产支持持久化的消息与队列
import pika

# 无密码
# connection = pika.BlockingConnection(pika.ConnectionParameters('123.206.16.61')) # 有密码
credentials = pika.PlainCredentials("admin","000000")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.193',credentials=credentials))
channel = connection.channel() # 声明一个队列(创建一个队列)
# 默认此队列不支持持久化,如果服务挂掉,数据丢失
# durable=True 开启持久化,必须新开启一个队列,原本的队列已经不支持持久化了 '''
实现rabbitmq持久化条件
delivery_mode=2
使用durable=True声明queue是持久化 '''
channel.queue_declare(queue='LOL',durable=True) #此步表示队列是支持持久化的参数
channel.basic_publish(exchange='',
routing_key='LOL', # 消息队列名称
body='我用双手成就你的梦想', # 支持数据持久化
# 代表消息是持久的 2
properties=pika.BasicProperties(
delivery_mode=2,
) )
connection.close()

  • 消费者代码
import pika

# 建立与rabbitmq的连接
# 前四行都是连接到同一个rabbitmq服务端以及同一个队列
credentials = pika.PlainCredentials("admin","000000")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.193',credentials=credentials))
channel = connection.channel()
channel.queue_declare(queue="LOL",durable=True) def callbak(ch,method,properties,body):
print("消费者取出了消息:%r"%body.decode("utf8")) # 有消息来临,立即执行callbak,没有消息则夯住,等待消息
channel.basic_consume(callbak,queue="LOL",no_ack=True) #no_ack 不用确认 # 开始消费,接收消息
channel.start_consuming()

当我重启rabbitmq这个服务之后,没有设置持久化的几个消息队列都被内存给杀死,而设置了持久化的消息队列没有任然存活;

消息队列之rabbitmq学习使用的更多相关文章

  1. RabbitMQ,Apache的ActiveMQ,阿里RocketMQ,Kafka,ZeroMQ,MetaMQ,Redis也可实现消息队列,RabbitMQ的应用场景以及基本原理介绍,RabbitMQ基础知识详解,RabbitMQ布曙

    消息队列及常见消息队列介绍 2017-10-10 09:35操作系统/客户端/人脸识别 一.消息队列(MQ)概述 消息队列(Message Queue),是分布式系统中重要的组件,其通用的使用场景可以 ...

  2. 快速入门分布式消息队列之 RabbitMQ(1)

    目录 目录 前言 简介 安装 RabbitMQ 基本对象概念 Message 消息 Producer 生产者 Consumer 消费者 Queue 队列 Exchange 交换机 Binding 绑定 ...

  3. Spring Boot 揭秘与实战(六) 消息队列篇 - RabbitMQ

    文章目录 1. 什么是 RabitMQ 2. Spring Boot 整合 RabbitMQ 3. 实战演练4. 源代码 3.1. 一个简单的实战开始 3.1.1. Configuration 3.1 ...

  4. 消息队列系统 -- RabbitMQ

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

  5. 消息队列之 RabbitMQ

    https://www.jianshu.com/p/79ca08116d57 关于消息队列,从前年开始断断续续看了些资料,想写很久了,但一直没腾出空,近来分别碰到几个朋友聊这块的技术选型,是时候把这块 ...

  6. 转 消息队列之 RabbitMQ

    转 https://www.jianshu.com/p/79ca08116d57 消息队列之 RabbitMQ 预流 2017.05.06 16:03* 字数 4884 阅读 80990评论 18喜欢 ...

  7. C# 消息队列之 RabbitMQ 进阶篇

    Ø  简介 在之前的 C# 消息队列之 RabbitMQ 基础入门 中介绍了 RabbitMQ 的基本用法,其实要更全面的掌握 RabbitMQ 这个消息队列服务,我们还需要掌握以下内容: 1.   ...

  8. 消息队列Rabbit MQ 学习第一篇

    1 介绍  1.1RabbitMQ MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队 ...

  9. 快速入门分布式消息队列之 RabbitMQ(3)

    目录 目录 前文列表 前言 通道 Channel 一个基本的生产者消费者实现 消费者 生产者 运行结果 应用预取计数 应用 ACK 机制 最后 前文列表 快速入门分布式消息队列之 RabbitMQ(1 ...

随机推荐

  1. ActiveMq PUT任意文件上传漏洞(CVE-2016-3088)漏洞复现

    漏洞原理 该漏洞出现在fileserver应用中,ActiveMQ中的fileserver服务允许用户通过HTTP PUT方法上传文件到指定目录.Fileserver支持写入文件(不解析jsp),但是 ...

  2. PHP可回调类型

    一些函数如usort和call_user_func()可以作为用户自对应函数做为回调参数,回调函数不止是简单的函数,还可以是对象的方法(类方法),包括静态方法. 用户自定义函数作为回调函数的参数,PH ...

  3. JQuery生成二维码,有资源下载

    原文链接:http://www.yxxrui.cn/article/65.shtml 没时间或者懒得看的,可以直接看加粗部分(或试试手感▼). 使用jquery.qrcode来生成二维码,qrcode ...

  4. [.NET] - 在Create一个RSA密钥的是要注意的长度问题

    有时候我们需要自己手动的创建RSA密钥,但是在密钥创建之后,在使用的时候会有类似密钥长度不正确的错误信息被抛出,那可能就是在创建一个RSA密钥的时候,对于的elements长度没设置正确,所以的ele ...

  5. Python常用内置对象

    1.在python中处理的一切都是对象. 2.内置对象可直接使用,如数字.字符串.列表.del等. 3.非内置对象需要导入模块才能使用,如正弦函数sin(x),随机数产生函数random()等.

  6. npm 各种常用命令

    全局删除 node-gyp npm -g uninstall node-gyp 再次安装依赖 npm install 更改包内容后重建 npm rebuild 清除缓存 npm cache clean ...

  7. JDK8-日期时间新方式

    日期时间新方式 ​ 在日常开发中,对于日期操作是非常常见的,但是对于有经验的开发人员来说Java8之前的日期操作是有较大问题 的.比方说SimpleDateFormat.但是在Java8之后提出了Da ...

  8. Android 音视频开发(一):PCM 格式音频的播放与采集

    什么是 PCM 格式 声音从模拟信号转化为数字信号的技术,经过采样.量化.编码三个过程将模拟信号数字化. 采样 顾名思义,对模拟信号采集样本,该过程是从时间上对信号进行数字化,例如每秒采集 44100 ...

  9. java中产品分类返回给前台页面 后台数据组装

    public ResultBean getSpfl(Integer yyb) { ResultBean res = new ResultBean(); try { JSONArray data = n ...

  10. ServletContext的作用

    一个项目只有一个ServletContext对象,一个tomcat有多个项目 作用:在多核Servlet中来获取这个唯一的对象,使用ta给多个Servlet传递数据. 在Tomcat启动时创建,在To ...