一、 功能和原理介绍
RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
AMQP,即Advanced message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。
AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。
1、设计集群的目的
a、 允许消费者和生产者在RabbitMQ节点崩溃的情况下继续运行
b、 通过增加更多的节点来扩展消息通信的吞吐量
2、 集群配置方式
RabbitMQ可以通过三种方法来部署分布式集群系统,分别是:cluster,federation,shovel
cluster: 不支持跨网段,用于同一个网段内的局域网, 可以随意的动态增加或者减少, 节点之间需要运行相同版本的RabbitMQ和Erlang
federation:应用于广域网,允许单台服务器上的交换机或队列接收发布到另一台服务器上交换机或队列的消息,可以是单独机器或集群。federation队列类似于单向点对点连接,消息会在联盟队列之间转发任意次,直到被消费者接受。通常使用federation来连接internet上的中间服务器,用作订阅分发消息或工作队列。
shovel:连接方式与federation的连接方式类似,但它工作在更低层次。可以应用于广域网。
3、 节点类型
RAM node:内存节点将所有的队列、交换机、绑定、用户、权限和vhost的元数据定义存储在内存中,好处是可以使得像交换机和队列声明等操作更加的快速。
Disk node:将元数据存储在磁盘中,单节点系统只允许磁盘类型的节点,防止重启RabbitMQ的时候,丢失系统的配置信息。
4、 Erlang Cookie
保证不同节点可以相互通信的密钥,要保证集群中的不同节点相互通信必须共享相同的Erlang Cookie。具体的目录存放在/var/lib/rabbitmq/.erlang.cookie
RabbitMQ底层是通过Erlang架构来实现的,所以rabbitmqctl会启动Erlang节点,并基于Erlang节点来使用Erlang系统连接RabbitMQ节点,在连接过程中需要正确的Erlang Cookie和节点名称,Erlang节点通过交换Erlang Cookie以获得认证。
5、集群模式
RabbitMQ的Cluster集群模式一般分为两种,普通模式和镜像模式。
普通模式:默认的集群模式,以两个节点(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高可用性。作用就是消息实体会主动在镜像节点之间实现同步,而不是像普通模式那样,在consumer消费数据时临时读取。缺点就是,集群内部的同步通讯会占用大量的网络带宽。
镜像队列实现了RabbitMQ的高可用性(HA),具体的实现策略如下所示:
语法讲解:
在cluster中任意节点启用策略,策略会自动同步到集群节点
#rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' # 应用于说有的队列,所以表达式为“^”
6、端口
TCP 4369:用于集群邻居发现;
TCP 5671、5672:用于AMQP clients使用;
TCP 15672:用于http api与rabbitadmin访问,后者仅限在management plugin开启时;
TCP 25672:用于erlang分布式节点/工具通信
二、部署
1、单节点部署
a、包安装
# yum install rabbitmq-server.noarch
# 配置文件在: /etc/rabbitmq/rabbitmq.config 配置文件使用 “%%” 注释配置
b、启动服务,设置开机自启动
# systemctl enable rabbitmq-server.service
# systemctl start rabbitmq-server.service
c、查看状态
# systemctl status rabbitmq-server.service -l
d、RABBITMQ页面(web)管理
management plugin默认就在RabbitMQ的发布版本中,
启用web插件
# rabbitmq-plugins enable rabbitmq_management
关闭web插件
# rabbitmq-plugins disable rabbitmq_management
浏览器访问:http://rabbitmq-server-IP:15672 如下图,账号密码随后创建。
e、Management plugin登录账号管理 (如果是集群,在一个节点修改,便可以全部生效,配置文件不会同步)
1、查看用户
# rabbitmqctl list_users
2、 guest账号
rabbit默认只有guest账号,可以使用guest:guest 登录web
3、CLI创建登录账号
# rabbitmqctl add_user username RABBIT_PASS (语法)
4、 设置账号的属性
# rabbitmqctl set_user_tags username administrator #用户设置为管理员角色
# rabbitmqctl set_permissions username ".*" ".*" ".*" #分配权限
5、登录
f、查看端口
--------------------到此,单节点配置完成。
2、集群部署--普通模式
a、环境
三台主机。系统: CentOS Linux release 7.4.1708 (Core)
主机名 IP 节点类型
cehp1 10.6.32.20 Master-Disk node
ceph2 10.6.32.21 slave-RAM node
ceph3 10.6.32.22 slave-RAM node
b、关闭从节点服务 (ceph2 、ceph3)
# rabbitmqctl stop
# systemctl stop rabbitmq-server.service
c、设置不同节点间同一认证的Erlang Cookie
采用从主节点copy的方式保持Cookie的一致性
# scp /var/lib/rabbitmq/.erlang.cookie root@ceph2:/var/lib/rabbitmq/.erlang.cookie
# scp /var/lib/rabbitmq/.erlang.cookie root@ceph3:/var/lib/rabbitmq/.erlang.cookie
d、启用节点,并查询状态
# rabbitmq-server -detached
# rabbitmqctl cluster_status
e、组建集群(ceph2、cehp3)
# rabbitmqctl stop_app
# rabbitmqctl join_cluster rabbit@ceph1 (rabbit代表集群名,ceph1代表集群节点,如果需要使用内存节点,增加一个”--ram“的参数即可,例:" rabbitmqctl join_cluster --ram rabbit@ceph1")
# rabbitmqctl start_app
# rabbitmqctl cluster_status
可以看出,加入集群后默认均为 disc node
f、修改 disc node 到 ram node
# rabbitmqctl stop_app
# rabbitmqctl change_cluster_node_type ram #(需要修改那个节点便在那个节点执行操作)
# rabbitmqctl start_app
g、web 查看状态
如果需要在web 看到从节点信息,需要在从节点上也开启web插件。
--------到此,默认集群配置完成。
维护:
如果要退出集群
1、从节点:(ceph3 为例)
#rabbitmqctl stop_app
# rabbitmqctl reset
# rabbitmqctl start_app
2、在集群主节点查看:
# rabbitmqctl cluster_status
3、镜像集群
在集群中执行即可
# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' # #所有队列都进行镜像
4、rabbitmq-web Haproxy 配置
#--------------------------------------------------------------------- # listen Rabbitmq-cluster-web server #--------------------------------------------------------------------- listen rabbitmq-web mode tcp bind 10.6.32.254:15671 balance roundrobin server controller1 10.6.32.20:15672 check inter 2000 rise 2 fall 5 server controller2 10.6.32.21:15672 check inter 2000 rise 2 fall 5 server controller3 10.6.32.22:15672 check inter 2000 rise 2 fall 5
openstack nova 调用 openstack:
# vim /etc/nova/nova.conf
[DEFAULT]
transport_url = rabbit://rabbitmq-username:RABBIT_PASS@controller1:5672,rabbitmq-username:RABBIT_PASS@controller2:5672,rabbitmq-username:RABBIT_PASS@controller3:5672
谢谢