消息队列之rabbitmq学习使用
消息队列之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学习使用的更多相关文章
- RabbitMQ,Apache的ActiveMQ,阿里RocketMQ,Kafka,ZeroMQ,MetaMQ,Redis也可实现消息队列,RabbitMQ的应用场景以及基本原理介绍,RabbitMQ基础知识详解,RabbitMQ布曙
消息队列及常见消息队列介绍 2017-10-10 09:35操作系统/客户端/人脸识别 一.消息队列(MQ)概述 消息队列(Message Queue),是分布式系统中重要的组件,其通用的使用场景可以 ...
- 快速入门分布式消息队列之 RabbitMQ(1)
目录 目录 前言 简介 安装 RabbitMQ 基本对象概念 Message 消息 Producer 生产者 Consumer 消费者 Queue 队列 Exchange 交换机 Binding 绑定 ...
- Spring Boot 揭秘与实战(六) 消息队列篇 - RabbitMQ
文章目录 1. 什么是 RabitMQ 2. Spring Boot 整合 RabbitMQ 3. 实战演练4. 源代码 3.1. 一个简单的实战开始 3.1.1. Configuration 3.1 ...
- 消息队列系统 -- RabbitMQ
消息队列系统 -- RabbitMQ RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Que ...
- 消息队列之 RabbitMQ
https://www.jianshu.com/p/79ca08116d57 关于消息队列,从前年开始断断续续看了些资料,想写很久了,但一直没腾出空,近来分别碰到几个朋友聊这块的技术选型,是时候把这块 ...
- 转 消息队列之 RabbitMQ
转 https://www.jianshu.com/p/79ca08116d57 消息队列之 RabbitMQ 预流 2017.05.06 16:03* 字数 4884 阅读 80990评论 18喜欢 ...
- C# 消息队列之 RabbitMQ 进阶篇
Ø 简介 在之前的 C# 消息队列之 RabbitMQ 基础入门 中介绍了 RabbitMQ 的基本用法,其实要更全面的掌握 RabbitMQ 这个消息队列服务,我们还需要掌握以下内容: 1. ...
- 消息队列Rabbit MQ 学习第一篇
1 介绍 1.1RabbitMQ MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队 ...
- 快速入门分布式消息队列之 RabbitMQ(3)
目录 目录 前文列表 前言 通道 Channel 一个基本的生产者消费者实现 消费者 生产者 运行结果 应用预取计数 应用 ACK 机制 最后 前文列表 快速入门分布式消息队列之 RabbitMQ(1 ...
随机推荐
- Java字节码中对应的JDK版本
Java class vs. JDK version mapping Java SE 9 = 53,Java SE 8 = 52,Java SE 7 = 51,Java SE 6.0 = 50,Jav ...
- 个人微信公众号搭建Python实现 -个人公众号搭建-被动回复消息建模(14.3.2)
@ 目录 1.阅读官方文档 2.思考 关于作者 1.阅读官方文档 点击进入微信官方开发者文档 接收普通消息 文本消息 图片消息 语言消息 视频消息 小视频消息 地理位置消息 链接消息 接收事件消息 关 ...
- matplotlib的学习15-次坐标轴
import matplotlib.pyplot as plt import numpy as np x = np.arange(0, 10, 0.1) y1 = 0.05 * x**2 y2 = - ...
- TP学习第二天—
一.控制器和对应方法的创建 2.路由解析 传统的路由解析方法: 具体url地址模式设置(配置文件在 ThinkPHP/Conf/convertion.php) 停到了之前的 黑马传智的 TP课,换了个 ...
- 只要肯下功夫,十岁也能学得会的 Docker 精简版!
目录 一.Docker简介 1.1 什么是Docker 1.2 Docker中包括三个基本的概念 1.3 Docker组件 1.4 安装Docker 二.Docker常用命令 三.应用部署 3.1 m ...
- win10新版wsl2使用指南
本篇文章会介绍win10中wsl2的安装和使用以及遇到的常见问题比如如何固定wsl2地址等问题的总结. 一.wsl2简介 wsl是适用于 Linux 的 Windows 子系统,安装指南:适用于 Li ...
- RestTemplate发起http请求中文乱码问题解决方案
RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); MediaType t ...
- [LeetCode]690. Employee Importance员工重要信息
哈希表存id和员工数据结构 递归获取信息 public int getImportance(List<Employee> employees, int id) { Map<Integ ...
- TurtleBot3使用课程-第三节b(北京智能佳)
目录 1.使用TurtleBot3机械手运行SLAM 2 1.1 roscore运行 2 1.2 准备行动 3 1.3 运行SLAM节点 3 1.4 运行turtlebot3_teleop_key节点 ...
- vue项目中使用日期获取今日,昨日,上周,下周,上个月,下个月的数据
今日公司项目接口要求获取动态的上周数据,经过不断的寻找,找到此方法. 该方法使用的是Moment.js JavaScript日期处理类库 一:安装依赖 npm install moment --sav ...