消息队列之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. CSS—— div+css

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. 单身狗福利!利用java实现每天给对象发情话,脱单指日可待!

    引言 最近看到一篇用js代码实现表白的文章,深有感触. 然后发现自己也可以用java代码实现,然后就开始写代码了,发现还挺有意思的,话不多说开搞 实现思路: 使用HttpClient远程获取彩虹屁生成 ...

  3. C#中的深度学习(一):使用OpenCV识别硬币

    在本系列文章中,我们将使用深度神经网络(DNN)来执行硬币识别.具体来说,我们将训练一个DNN识别图像中的硬币. 在本文中,我们将描述一个OpenCV应用程序,它将检测图像中的硬币.硬币检测是硬币完整 ...

  4. Android面试系列一

    什么是ANR,如何避免它 ​ ANR是应用程序无响应(Application Not Responding)的的英文缩写: ​ 当Android 手机在一段时间响应不够灵敏,系统会向用户展示一个对话框 ...

  5. Spring AOP 实战运用

    Spring AOP 实战 看了上面这么多的理论知识, 不知道大家有没有觉得枯燥哈. 不过不要急, 俗话说理论是实践的基础, 对 Spring AOP 有了基本的理论认识后, 我们来看一下下面几个具体 ...

  6. Thread通信与唤醒笔记1

    synchronized if判断标记,只有一次,会导致不该信息的线程运行了,出现了数据错误的情况 while判断标记,解决了线程获取执行权之后,是否要运行! notify 只能唤醒一个任意线程,如果 ...

  7. centos7下mysql安装与卸载

    彻底卸载mysql 一.chak 是否有安装mysql a)      rpm -qa | grep -i mysql // 查看命令1 b)      yum list install mysql* ...

  8. Oracle RedoLog-基本概念和组成

    Oracle 数据库恢复操作最关键的依据就是 redo log,它记录了对数据库所有的更改操作.在研究如何提取 redolog 中 DML 操作的过程可谓一波三折,因为介绍 redolog 结构细节的 ...

  9. Linux 设置静态IP

    由于工作需要,安装一套Linux系统.安装完成后发现这个家伙居然不能上网,然后看了下IP,(命令 ip a)发现是127.0.0.1 下面是我的界面: inet 是127.0.0.1/8 还有6个网卡 ...

  10. swack的wiki站上线

    swack的个人wiki网址:www.swack.cn [服务器破旧,速度较慢,见谅!]