文章目录
RabbitMQ的一些概念
之前文章介绍了队列的一些普遍概念和基本原理这是个链接,这里要详细说说我们使用的RabbitMQ的涉及到的概念
- RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queuing Protocol)【高级消息队列协议】
RabbitMQ架构图
解释一下这个架构图
- 可以看到生产者Publisher并没有将消息直接发送到消息队列,而是增加了交换机Exchange和Binding。
- 生产者把消息发布到交换机,Binding决定了交换机Exchange的消息应该发送到哪个队列
- 消费者Consumer通过建立消息队列Queue相连的管道Channel,从消息队列Queue中获取消息
解释一下这些英文术语
Message
- 消息:消息是不具名的,由消息头和消息体组成,消息体是不透明的,
- 消息头则由一系列的可选的属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指该消息可能需要持久性存储)等
Publisher
- 消息的生产者,消息的来源者
Exchage
- 交换机,用于接收生产者发送的消息并将这些消息路由给服务器中的队列
- 说点人话就是,它指定消息按什么规则,路由到哪个队列
- Exchage有4种类型,不同类型的Exchage转发消息的策略也有所区别
direct:默认,将消息中的Routing key与该Exchange关联的所有Binding中的Routing key进行比较,如果相等,则发送到该Binding对于的Queue中,使用这个类型的时候,可以不必指定Routing key的名字,在此类型下创建的Queue有一个默认的Routing key ,这个Routing key一般与Queue同名
fanout:直接将消息转发到所有Binding对应的Queue中,这种Exchange在路由转发的时候,忽略Routing key,也就是***广播***
topic:将消息中的Routing key与该Exchange关联的所有Binding中的Routing key进行对比,如果匹配上了(注意这里是匹配而不是相等),则发送到该Binding对应的Queue中。
headers:这个是根据Message的一些头部信息与该Exchage相关联的所有Binding中的参数进行匹配,忽略了Routing key的属性
Queue
- 消息队列,消息的容器,用于保存消息直到发送给消费者,一个消息可以投入一个或多个队列。
Binding
- 绑定,用于消息队列和交换机之间关联
- 一个绑定就是基于Routing key(路由键)将交换机和消息队列链接起来的路由规则,所以可以理解交换机实际上是一个由绑定构成的路由表
- Exchange和Queue的绑定可以是多对多的关系
Connection
- 网络连接,比如一个TCP连接
Channel
- 信道,多路复用连接中的一条独立的双向数据流通道
- 信道是建立在真实的TCP连接内的虚拟连接
- AMQP的命令都是通过信道发出去的,不论是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。
- 信道的出现是源于,对于操作系统来说建立和销毁TCP连接都是比较昂贵的开销,所以引入了信道的概念,复用一个TCP连接
Consumer
- 消息的消费者 ,即从消息队列中取得消息的程序
Virtual Host
- 虚拟主机,表示一批交换机、消息队列和相关对象。
- 虚拟主机是共享相同的身份认证和加密环境的独立服务器域
- 每个Virtual Host的实际就是一个mini的RabbitMQ服务器,拥有自己的队列、消息交换机、绑定和权限机制
- Virtual Host是AMQP概念的基础,必须再连接时指定,RabbitMQ默认的Virtual Host是/
Broker
- 消息队列服务器实体
Docker安装RabbitMQ
环境
- 虚拟机:Centos7
- 远程工具:Xshell6
- docker版本:19.03.12
开始安装
- 首先,启动docker拉取RabbitMq镜像
启动docker的命令
systemctl restart docker
拉取Rabbitmq镜像命令
docker pull rabbitmq:management
management是rabbitmq的版本,你也可以用其他版本,随你喜欢
正常拉取的过程就是下图这个样子了
- 然后我们看一下拉下来的镜像
查看所有镜像命令
docker images
- 然后启动镜像,注意端口号映射,还挺多的
docker run -id --name=rabbitmq --hostname rabbitmq -p 5671:5671 -p 4369:4369 -p 15672:15672 -p 25672:25672 rabbitmq:management
推荐使用下面这个命令,因为上面命令不知道为何,当你想用java操作时,一直在报连接不上的错
docker run -d --restart=always -p 15672:15672 -p 5672:5672 -e RABBITMQ_DEFAULT_USER=guest -e RABBITMQ_DEFAULT_PASS=guest rabbitmq:management
5671,5672端口: AMQP 0-9-1 without and with TLS的默认端口号,AMQP前面说过是一个提供统一消息服务的应用层标准高级消息队列协议。
4369端口: empd的默认端口号,empd【Erlang Port Mapper Daemon】代表Erlang端口映射守护进程,在Erlang集群中相当于DNS作用,可以使用empd -names
命令来查看当前运行的empd中绑定注册的端口号即监听的分发端口号
15672端口: 默认用于访问RabbitMQ的web管理界面的端口号
25672端口: Erlang分发服务器端口,
其他的一些端口: 61613、61614(STOMP默认端口号,Stomp是一个简单的消息文本协议) 1883、8883(MQTT默认端口号,MQTT是一个基于TCP/IP的消息协议。两个App端的消息和发送需要中间人,即中间人RabbitMQ,而这三者之间的通信协议就是MQTT)
- 启动了后,我们就可以用doker命令看一下起来的容器
docker ps
当下次发现Rabbitmq的容器还存在,但是docker ps中没有Rabbitmq时,可以用命令docker restart 容器ID
来重启容器
到此,已经安装完毕,以下是验证
- 我们在本地主机的浏览器里输入ip:15672访问RabbitMQ的web管理界面,密码和用户名都在图里了
- 登录成功后,成功进入的RabbitMQ是下图这样的
可能会出现的问题
你可能会发现当你下一次重启rabbitmq的容器后,访问不到web界面了,这时候,不要慌,冷静的上个网
首先,使用docker stop 容器ID
让容器运行停止,然后再使用docker rm 容器ID
删除rabbitmq运行的容器
然后再使用docker run -id --name=rabbitmq --hostname rabbitmq -p 5671:5671 -p 4369:4369 -p 15672:15672 -p 25672:25672 rabbitmq:management
运行rabbitmq,这时候你就可以看到问题所在了[ps:感动啊,感动的痛苦流涕啊😭]
然后如果你是一个幸运儿的话,你可以看到以下报错:
这个时候容器虽然启动了,但是web界面根本访问不到
这个报错不是因为你人品不好,而是因为CentOS的内核中的ip_forward(IP转发)是默认关闭的,需要手动打开。
好了,我废话太多了,以下是解决方案
vim /etc/sysctl.conf
或者
vim /usr/lib/sysctl.d/00-system.conf
打开该配置文件后,添加一行代码
net.ipv4.ip_forward=1
添加完成后保存,像这样
重启network服务
systemctl restart network
查看是否修改成功
sysctl net.ipv4.ip_forward
重启docker容器
如果你是docker启动报这个错就重启docker
systemctl restart docker
像我的情况,是重启rabbitmq的容器时报了这个错,那我就只重启了rabbitmq容器
docker restart rabbitmq容器ID
通过Web界面使用RabbitMQ
可以看到主页面主要由6个大模块组成:OverView(概览)、Connections(监控所有的连接)、Channels(信道)、Exchange(交换机)、Queues(消息队列)、Admin(管理控制台)
Admin(管理控制台)
- 用户管理
User这里可以查看或添加用户,添加用户时,可以指定Tags,相当于指定用户的角色,不同角色会有不同的权限
- 新增用户
添加完成后你可以在All users中看到
No access说明的是该用户还没有和虚拟主机进行绑定,也就是说只是有了该用户,但还不能进行实质操作
我们点击用户名进入权限设置
会进入到一个用户设置的页面,然后找到Permissions模块,我们设置权限
再看用户时,就会发现dean用户有了虚拟主机/
当然,如果你不想使用这个虚拟主机了,你也可以再次点击用户名进入该页面进行清除
- 新增一个虚拟主机
我们来为自己创建的用户创建一个可供使用的虚拟主机
可以看到成功创建
我们将用户dean和新建的虚拟机绑定
可以看到,虽然guest我们没有进行手动绑定,但是guest和虚拟机/x还是绑定了,原因是guest默认拥有所有虚拟主机的操作权限,你可以手动清除
Queue(消息队列)
- 新增一个队列
创建完毕后,点击队列名称可以对队列进行操作
- 向队列中放入一条消息
- 从队列中获取消息
Exchages(交换机)
RabbitMQ中默认有7个交换机,就好像mysql中默认会有几张系统表一样
- 新增交换机
- 交换机和队列相绑定
点击交换机名称,可以进入交换机设置页面,对交换机进行操作
点击Bindings进行绑定
绑定完成后,我们在Exchanges下的Publish message根据路由键推送消息到绑定的队列中
消息推送完成后,切换到Queues模块获取消息进行验证
可以看到队列中已经有消息了。
至此,RabbitMQ的web界面使用就结束了,剩余的几个模块需要使用代码操作,Web界面只是用于查看信息