Skip to content

rabbitmq环境搭建

以下环境均用docker部署。集群的**节点通信:**集群需要保证各个节点有相同的token令牌,防止非法节点进入盗取信息

erlang.cookie是erlang的分布式token文件,集群内各个节点的erlang.cookie需要相同,才可以互相通信

一、端口介绍

4369 erlang 发现口
5672 client 端通信口
15672 管理界面 ui 端口
25672 server 间内部通信口

二、单机

RabbitMQ默认创建了一个 guest 用户,密码也是 guest,15672是控制台地址。如果需要自定义,可以通过一下方式进行配置

docker pull rabbitmq:management
#hostname是主机名称
docker run -d --name=rabbitmq --hostname=rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management
#带有密码的,但是在Rabbitmq 3.9 后移除了这个变量
docker run -d --name=rabbitmq --hostname=rabbitmq -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin  rabbitmq:management

三、普通集群

默认的集群模式, 比如有节点 node1和node2、node3,三个节点是普通集群,但是他们仅有相同的元数据,即交换机、队列的结构;

发送或者消费消息的时候,会根据集群的规则进行存储,如轮训策略等。

存储介绍:

当队列消息发送过来,存放在了node1上,如果消费者消费的时候是进入到了node1节点获取,则可以直接消费,如果消费者消费的时候进入到的是其它节点,其它节点会把 queue 中的消息从node1中取出, 并经过连接节点转发后再发送给消费者。

问题:

当node1节点发生故障的时候,消息无法被立即消费,不能实现高可用。如果node1做了持久化,等node1进行数据恢复以后才能正常消费;如果node1没有进行持久化,node1的数据就会丢失。

应用场景:

该模式更适合于消息无需持久化的场景,如日志传输的队列

容器创建:

#节点一,主节点,创建-v映射目录
docker run -d --hostname rabbit_host1 --name rabbitmq-node1 -p 15672:15672 -p 5672:5672 -e RABBITMQ_NODENAME=rabbit -e RABBITMQ_ERLANG_COOKIE='rabbitmq_cookie' --privileged=true -v /software/rabbitmq/node1/lib:/var/lib/rabbitmq -v /software/rabbitmq/node1/log:/var/log/rabbitmq rabbitmq:management

#节点二,创建-v映射目录
docker run -d --hostname rabbit_host2 --name rabbitmq-node2  -p 15673:15672 -p 5673:5672 --link rabbitmq1:rabbit_host1 -e RABBITMQ_NODENAME=rabbit -e RABBITMQ_ERLANG_COOKIE='rabbitmq_cookie' --privileged=true -v /software/rabbitmq/node2/lib:/var/lib/rabbitmq -v /software/rabbitmq/node2/log:/var/log/rabbitmq rabbitmq:management

#节点三,创建-v映射目录
docker run -d --hostname rabbit_host3 --name rabbitmq-node3 -p 15674:15672 -p 5674:5672 --link rabbitmq1:rabbit_host1 --link rabbitmq2:rabbit_host2 -e RABBITMQ_NODENAME=rabbit -e RABBITMQ_ERLANG_COOKIE='rabbitmq_cookie' --privileged=true -v /software/rabbitmq/node3/lib:/var/lib/rabbitmq -v /software/rabbitmq/node3/log:/var/log/rabbitmq rabbitmq:management

集群配置:

主节点(磁盘节点)的配置

#进入容器
docker exec -it rabbitmq-node1 bash
#停止rabbitmq
rabbitmqctl stop_app
#重新设置
rabbitmqctl reset
#启动
rabbitmqctl start_app
#退出
exit

其它节点加入:

docker exec -it rabbitmq-node2 bash
rabbitmqctl stop_app
#节点加入集群,--ram是以内存方式加入,忽略该参数默认为磁盘节点。
rabbitmqctl join_cluster --ram rabbit@rabbit_host1
rabbitmqctl start_app
exit

查看集群状态:

rabbitmqctl cluster_status

集群重启顺序

集群重启的顺序是固定的,并且是相反的

  • 启动顺序:磁盘节点 => 内存节点

  • 关闭顺序:内存节点 => 磁盘节点

最后关闭必须是磁盘节点,否则容易造成集群启动失败、数据丢失等异常情况

四、镜像集群

队列做成镜像队列,让各队列存在于多个节点中和普通集群比较大的区别就是【队列queue的消息message 】会在集群各节点之间同步,且并不是在 consumer 获取数据时临时拉取, 而普通集群则是临时从存储的节点里面拉取对应的数据

优点:

  • 实现了高可用性,部分节点挂掉后,不影响正常的消费

  • 可以保证100%消息不丢失,推荐3个奇数节点,结合LVS+Keepalive进行IP漂移,防止单点故障

缺点:

由于镜像队列模式下,消息数量过多,大量的消息同步也会加大网络带宽开销,适合高可用要求比较高的项目过多节点的话,性能则更加受影响

配置镜像集群

镜像集群是在普通集群的基础上通过策略policy进行配置,实现消息和交换机可以自动同步

策略policy

rabbitmq的策略policy是用来控制和修改集群的vhost队列和Exchange复制行为,就是要设置哪些Exchange或者queue的数据需要复制、同步,以及如何复制同步

步骤:

  1. rabbitmq管理页面 —> Admin —> Policies —> Add / update a policy

  2. 参数: 策略会同步同一个VirtualHost中的交换器和队列数据

    • name:自定义策略名称

    • Pattern:^ 匹配符,代表匹配所有

    • Definition:ha-mode=all 为匹配类型,分为3种模式:all(表示所有的queue)

      ha-mode: 指明镜像队列的模式,可选下面的其中一个
        all:表示在集群中所有的节点上进行镜像同步(一般都用这个参数)
        exactly:表示在指定个数的节点上进行镜像同步,节点的个数由ha-params指定
        nodes:表示在指定的节点上进行镜像同步,节点名称通过ha-params指定
      
      ha-sync-mode:镜像消息同步方式 automatic(自动--),manually(手动)