RabbitMQ的高可用集群部署
标签(空格分隔): 消息队列 部署
1. RabbitMQ部署的三种模式
1.1 单一模式
单机情况下不做集群, 仅仅运行一个RabbitMQ.
# docker-compose.yml
version: '3.1'
services:
rabbitmq:
restart: always
image: rabbitmq:management
container_name: rabbitmq
ports:
- 5672:5672
- 15672:15672
environment:
TZ: Asia/Shanghai
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: 123456
volumes:
- ./data:/var/lib/rabbitmq
1.2 普通模式
默认模式,以两个节点(
rabbits01
,rabbits02
)为例来说明. 对于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
的.erlang.cookie
的值一致化. - 确保不同的机器之间可以相互访问
ping
通.
version: '3.1'
services:
myrabbit01:
restart: always
image: rabbitmq:management
container_name: myrabbit01
ports:
- 5672:5672
- 15672:15672
environment:
TZ: Asia/Shanghai
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: 123456
RABBITMQ_ERLANG_COOKIE: rabbitcookie
volumes:
- ./data:/var/lib/rabbitmq
hostname:
rabbit01
network_mode: bridge
version: '3.1'
services:
myrabbit02:
restart: always
image: rabbitmq:management
container_name: myrabbit02
ports:
- 5673:5672
- 15673:15672
environment:
TZ: Asia/Shanghai
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: 123456
RABBITMQ_ERLANG_COOKIE: rabbitcookie
volumes:
- ./data:/var/lib/rabbitmq
extra_hosts:
- rabbit01 myrabbit01:172.17.0.2
hostname:
rabbit02
network_mode: bridge
# 添加 集群
docker exec -it myrabbit02 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbit01
rabbitmqctl start_app
exit
- 其实还没有做到高可用,
Spring Boot
配置文件如下
spring:
application:
name: spring-boot-amqp
rabbitmq:
username: admin
password: 123456
addresses: 192.168.219.151:5673,192.168.219.151:5672
- 如果主节点挂了, 那么还是全局崩盘, 因为数据都在主节点上面存储, 配置从节点的主要原因就是害怕主节点的输出量太大造成瓶颈, 如果在从节点取数据的话, 可以适当减轻主节点压力. 不过这种方法 挺弱智的.
1.3 镜像模式
把需要的队列做成镜像队列, 这样不管连接那个节点, 都可以顺利的存取数据, 解决了普通模式的问题.
缺点也很明显, 这样在不同的节点内复制数据会明显的降低系统性能, 集群内的网络带宽会被大大的消耗掉.
- 这种情况仅仅对于那种 对可用性要求比较高的场合中使用.
镜像模式首先要依赖
policy
模块, 这个模块是怎么用的呢?
policy
中文意思是政策,策略. 按照这个策略 那些Exchange
或者Queue
的数据需要复制,同步,那么如何做呢? 其实也就是在1.2的基础上, 在主节点上设置如下:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
参数意思:
ha-all
-为策略名称.^
,^zlh
为匹配名称为zlh
的exchange
或者Queue
.
ha-mode
: 为匹配类型, 他分为三种模式:all
-所有(所有的queue
),exctly
-部分(需配置ha-params
参数,此参数为int
类型比如3
,众多集群中的随机3
台机器),nodes
-指定(需配置ha-params
参数,此参数为数组类型比如["3rabbit@F","rabbit@G"]
这样指定为F
与G
这2
台机器。)。
总结
现在的各种云还是比较稳定的, 使用普通模式其实就已经够用了.