生产者先将消息投递一个叫做「队列」
的容器中,然后再从这个容器中取出消息,最后再转发给消费者,仅此而已
消息队列服务RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)
☺核心概念
RabbitMQ是一个开源的消息代理软件。它接收生产者
发布的消息并发送给消费者
。它扮演中间商的角色,可以用来降低web服务器因发送消息带来的负载以及延时。
▷ 生产者Producer: 发送消息的应用。
▷ 消费者Consumer:接收消息的应用。
▷ 队列Queue:存储消息的缓存。
▷ 消息Message: 生产者通过RabbitMQ发送给消费者的信息。
▷ 连接Connection:连接RabbitMQ和应用服务器的TCP连接。
▷ 通道Channel:连接里的一个虚拟通道。当你通过消息队列发送或者接收消息时,这个操作都是通过通道进行的。
▷ 交换机Exchange:从生产者那里接收消息,并根据交换类型分发到对应的消息列队里。要实现消息的接收,一个队列必须绑定一个交换机。
▷ 绑定Binding:绑定是队列和交换机的一个链接。
▷ 路由键Routing Key:路由键是供交换机查看并根据键的值来决定如何分发消息到列队的一个键。路由键可以说是消息的目的地址。
▷ AMQP:高级消息队列协议(Advanced Message Queuing Protocol)是RabbitMQ使用的消息协议。
▷用户Users:在RabbitMQ里,是可以通过指定的用户名和密码来进行连接的。每个用户可以分配不同的权限,例如读权限,写权限以及在实例里进行配置的权限。
①单一模式:即单机情况不做集群,就单独运行一个rabbitmq而已。
②普通模式:默认模式,以两个节点(rabbit01、rabbit02)为例来进行说明。
对于Queue来说,消息实体只存在于其中一个节点rabbit01(或者rabbit02),rabbit01和rabbit02两个节点仅有相同的元数据,即队列的结构。当消息进入rabbit01节点的Queue后,consumer从rabbit02节点消费时,RabbitMQ会临时在rabbit01、rabbit02间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连rabbit01或rabbit02,出口总在rabbit01,会产生瓶颈。当rabbit01节点故障后,rabbit02节点无法取到rabbit01节点中还未消费的消息实体。如果做了消息持久化,那么得等rabbit01节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。
③镜像模式:把需要的队列做成镜像队列,存在于多个节点属于RabbitMQ的HA方案。
该模式解决了普通模式中的问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用。
node1 192.168.1.1
node2 192.168.1.2
node3 192.168.1.3
安装启动过程中如果出现error,那可参考下面几个方案试试:
☑ 1、vim /etc/rabbitmq/enable_plugins :删除文件中的内容
☑ 2、查看hosts文件是否配置完善,相互是否可以ping通
☑ 3、查看相关端口是否被占用,如若占用kill掉
☑ 4、如果已经集群,那么要查看所有集群中的/var/lib/rabbitmq/.erlang.cookie是否一致。
☑ 5、重启电脑,防止缓存数据配置未更新过来
ErlangGithub地址
RabbitMQGithub地址
yum -y install socat
rpm -ivh erlang-18.1-1.el7.centos.x86_64.rpm
rpm -ivh rabbitmq-server-3.6.15-1.el7.noarch.rpm
hostnamectl set-hostname node1
bash
[root@node1 ~]# echo "192.168.1.1 node1" >>/etc/hosts
[root@node1 ~]# echo "192.168.1.2 node1" >>/etc/hosts
[root@node1 ~]# echo "192.168.1.3 node3" >>/etc/hosts
[root@node1 ~]# scp /etc/hosts root@192.168.1.2:/etc/
[root@node1 ~]# scp /etc/hosts root@192.168.1.3:/etc/
[root@node1 ~]# reboot
iptables -F
[root@node1 ~]# systemctl start rabbitmq-server rabbitmq-server -deched --后台启动服务(这种方法不太可取)
[root@node2 ~]# netstat -anpt | grep 5672
tcp 0 0 0.0.0.0:25672 0.0.0.0:* LISTEN 3477/beam
tcp6 0 0 :::5672 :::* LISTEN 3477/beam
[root@node1 ~]# rabbitmqctl cluster_status --
Cluster status of node rabbit@node1
[{nodes,[{disc,[rabbit@node1]}]},
{running_nodes,[rabbit@node1]},
{cluster_name,<<"rabbit@node1">>},
{partitions,[]},
{alarms,[{rabbit@node1,[]}]}]
[root@node1 ~]# cat /var/lib/rabbitmq/.erlang.cookie
IOHLYSVDOUNOKMCNSZBB
[root@node1 ~]# scp /var/lib/rabbitmq/.erlang.cookie root@192.168.1.2:/var/lib/rabbitmq/
[root@node1 ~]# scp /var/lib/rabbitmq/.erlang.cookie root@192.168.1.3:/var/lib/rabbitmq/
>RabbitMQ的集群是依赖erlang集群,而erlang集群是通过cookie进行通信认证的
[root@node1 ~]# systemctl restart rabbitmq-server
[root@node1 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@node1
[{nodes,[{disc,[rabbit@node1]},{ram,[rabbit@node3,rabbit@node2]}]},
{running_nodes,[rabbit@node3,rabbit@node2,rabbit@node1]},
{cluster_name,<<"rabbit@node1">>},
{partitions,[]},
{alarms,[{rabbit@node3,[]},{rabbit@node2,[]},{rabbit@node1,[]}]}]
[root@node1 ~]# rabbitmq-plugins enable rabbitmq_management
The following plugins have been enabled:
amqp_client
cowlib
cowboy
rabbitmq_web_dispatch
rabbitmq_management_agent
rabbitmq_management
Applying plugin configuration to rabbit@node1... started 6 plugins.
[root@node1 ~]# rabbitmqctl delete_user guest 删除原来的用户
Deleting user "guest"
[root@node1 ~]# rabbitmqctl add_user zhao 123.com 创建用户+密码
Creating user "zhao"
[root@node1 ~]# rabbitmqctl set_user_tags zhao administrator 设置用户具有administrator权限
Setting tags for user "zhao" to [administrator]
# 访问测试
[root@node1 ~]# firefox 192.168.1.1:15672
配置完之后reboot
[root@node2 ~]# systemctl start rabbitmq-server
[root@node2 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@node2
[{nodes,[{disc,[rabbit@node2]}]},
{running_nodes,[rabbit@node2]},
{cluster_name,<<"rabbit@node2">>},
{partitions,[]},
{alarms,[{rabbit@node2,[]}]}]
[root@node2 ~]# cat /var/lib/rabbitmq/.erlang.cookie
IOHLYSVDOUNOKMCNSZBB
[root@node2 ~]# systemctl restart rabbitmq-server
···时间较长请耐心等待~
[root@node2 ~]# reboot “重启完之后别忘了启动rabbitmq”
iptables -F
[root@node2 ~]# systemctl start rabbitmq-server
[root@node2 ~]# rabbitmqctl stop_app //关闭服务
Stopping rabbit application on node rabbit@node2
[root@node2 ~]# rabbitmqctl join_cluster rabbit@node1 --ram #将node2和node3以内存的形式添加到node1的节点中
Clustering node rabbit@node2 with rabbit@node1
[root@node2 ~]# rabbitmqctl start_app //启动服务
Starting node rabbit@node2
[root@node2 ~]# rabbitmq-plugins enable rabbitmq_management
[root@node2 ~]# cd /var/lib/rabbitmq/mnesia/rabbit@node2/queues/
[root@node2 queues]# ls
6YWL9IU4EJTYH7IP54ORYOUHP
同node2
[root@node3 ~]# cd /var/lib/rabbitmq/mnesia/rabbit@node3/queues/
[root@node3 queues]# ls
6YWL9IU4EJTYH7IP54ORYOUHP
1、浏览器访问15672端口(默认队列用的是5672端口,UI用的是15672端口),用默认的 guest/guest登录 然而此时我浏览器访问的时候却遇到这样一个情况:UI管理端口被拒绝了
解决方法:
这是因为当前的UI插件还没有启动,执行下面命令即可。
rabbitmq-plugins enable rabbitmq_management # 启动管理插件
2、使用guest访问时发现该账户是有访问限制的。
解决方法:需要手动添加一个用户,并且用户权限也要设置为administrator。然后就可以使用admin账号进行登录了!
rabbitmqctl add_user admin 123456 #设置用户账号和密码
rabbitmqctl set_user_tags zhao administrator #设置权限
rabbitmqctl是RabbitMQ中间件的一个命令行管理工具,原理就是通过连接一个中间件的节点执行所有的动作,本地节点默认为rabbit
,rabbitmqctl来指定RabbitMQ中间件在本地节点rabbit@localhost进行管理操作。
注意
:在使用rabbitmqctl命令时,可以用-n标志来明确指定的节点,比如rabbitmqctl -n rabbit@localhost …
,在使用默认节点的情况下这个可以省略。
▷ 应用管理
rabbitmqctl status //显示RabbitMQ中间件的所有信息
rabbitmqctl stop //停止RabbitMQ应用,关闭节点
rabbitmqctl stop_app //停止RabbitMQ应用
rabbitmqctl start_app //启动RabbitMQ应用
rabbitmqctl restart //重置RabbitMQ节点
rabbitmqctl force_restart //强制重置RabbitMQ节点
▷ 用户管理
rabbitmqctl add_user username password //添加用户
rabbitmqctl delete_user username //删除用户
rabbitmqctl change_password username newpassword //修改密码
rabbitmqctl list_users //列出所有用户
▷ 权限控制管理
rabbitmqctl add_vhost vhostpath //创建虚拟主机
rabbitmqctl delete_vhost vhostpath //删除虚拟主机
rabbitmqctl list_vhosts //列出所有虚拟主机
rabbitmqctl set_permissions [-p vhostpath] username <conf> <write> <read> //设置用户权限
rabbitmqctl clear_permissions [-p vhostpath] username //删除用户权限
rabbitmqctl list_permissions [-p vhostpath] //列出虚拟机上的所有权限
rabbitmqctl list_user_permissions username //列出用户权限
▷ 集群管理
rabbitmqctl cluster_status //获得集群配置信息
rabbitmqctl join_cluster rabbit@localhost --ram | --disc //加入到rabbit节点中,使用内存模式或者磁盘模式
rabbitmqctl change_cluster_node_type disc | ram //修改存储模式
rabbitmqctl set_cluster_name newname //修改名字
▷ 查看管理
rabbitmqctl list_queues [-p <vhostpath>] //查看所有队列
rabbitmqctl list_exchanges [-p <vhostpath>] //查看所有交换机
rabbitmqctl list_bindings [-p <vhostpath>] //查看所有绑定
rabbitmqctl list_connections //查看所有连接
rabbitmqctl list_channels //查看所有信道
rabbitmqctl list_consumers //查看所有消费者信息
RabbitMQ通过使用RabbitMQ Management
插件的Web界面来管理用户、队列和交换器。
Web界面包含的内容:
✔ 服务器数据统计概览
✔ 导入/导出服务器配置
✔ 监控服务器连接
✔ 信道列表
✔ 交换器列表、添加交换器
✔ 队列列表、添加队列
✔ 修改队列绑定
✔ 用户列表、添加用户
✔ 查看vhost、添加vhost
注意:
使用rabbitmq-plugins enable rabbitmq_management来启动Management插件。 默认是可以本地登录localhost:15672,用户名/密码guest/guest;端口默认15672。
在web界面上还有两个选项,HTTP API和CLT。
☑ HTTP API:提供了一个关于REST接口的文档界面,Web界面可以完成的功能,都可以通过使用curl并调用API命令来完成。比如需要列出服务器上的vhost的话,在终端执行下列代码即可:
curl -i -u 用户:密码 http://localhost:15672/api/vhosts
☑ CLI:主要是Python脚本,相比于REST的API好处是,不需要手工编写请求,rabbitmqadmin会包装REST API,使用干净的接口与其交互,举例来说:
curl -i -u 用户:密码 http://localhost:15672/api/queues //使用REST API
./rabbitmqadmin list queues //使用CLI
☑ rabbitmqadmin脚本安装
wget http://localhost:15672/cli/rabbitmqadmin
chmod +x rabbitmqadmin
总结:
三种管理方式各有特点:
▷ Web UI对于日常的开发更加简单,可以通过视图查看服务器的状态,方便观察。
▷ REST API可以自动化这些任务,并通过curl来调用,得到JSON对象后就可以集成到当前的工具和语言中。
▷ rabbitmqadmin脚本不需要手工构造通过curl发送的HTTP请求,获得更加简介易懂的格式化输出,帮助管理和监控RabbitMQ。
官网配置地址
在大多数系统上,节点应该能够以所有默认值启动和运行。
注意:该节点设置为以系统用户rabbitmq运行。如果节点数据库或日志的位置发生了变化,则文件和目录必须为该用户所有。
RabbitMQ节点绑定到端口(打开服务器TCP套接字)以接受客户端和CLI工具连接。其他进程和工具,如SELinux,可能会阻止RabbitMQ绑定到端口。当这种情况发生时,节点将无法启动。
CLI工具、客户端库和RabbitMQ节点也可以打开连接(客户端TCP套接字)。防火墙可以阻止节点和CLI工具之间的通信。确保以下端口是可访问的:
# 可以配置RabbitMQ使用不同的端口和特定的网络接口。
4369 epmd,RabbitMQ节点和CLI工具使用的对等发现服务
5672、5671 由不带和带 TLS 的 AMQP 0-9-1 和 1.0 客户端使用
25672 用于节点间和CLI工具通信(Erlang分发服务器端口),并从动态范围进行分配(默认情况下限于单个端口,计算为AMQP端口+ 20000)。除非这些端口上的外部连接确实有必要(例如,群集使用联合或在子网外的机器上使用CLI工具),否则这些端口不应公开
35672-35682 由CLI工具(Erlang分发客户端端口)用于与节点通信,并从动态范围(计算为服务器分发端口+ 10000到服务器分发端口+ 10010)进行分配
15672 HTTP API客户端、管理UI和rabbitmqadmin(仅当启用了管理插件时)
61613、61614 不带和带 TLS 的STOMP 客户端(仅在启用STOMP 插件的情况下)
1883、8883 如果启用了MQTT插件,则MQTT客户机可以不使用TLS,也可以使用TLS
15674 STOMP-over-WebSockets客户端(仅当Web STOMP插件启用时)
15675 MQTT-over-WebSockets客户端(仅当启用了Web MQTT插件时)
15692 Prometheus 指标(仅在启用Prometheus 插件的情况下)
默认用户访问
代理创建一个用户guest,密码为 guest。未配置的客户端通常会使用这些凭据。默认情况下这些凭据只能在以 localhost 连接到代理时使用,因此您需要在从任何其他计算机连接之前采取措施。
Although a person is ambitious, but life is difficult to also need to work hard !