RabbitMQ常见问题之高可用

文章目录

一、集群分类

RabbitMQ的是基于Erlang语言编写,而Erlang又是一个面向并发的语言,天然支持集群模式。RabbitMQ的集群有两

种模式:

  • 普通集群:是一种分布式集群,将队列分散到集群的各个节点,从而提高整个集群的并发能力。
  • 镜像集群:是一种主从集群,普通集群的基础上,添加了主从备份功能,提高集群的数据可用性。

镜像集群虽然支持主从,但主从同步并不是强一致的,某些情况下可能有数据丢失的风险。因此在RabbitMQ3.8版本

以后,推出了新的功能------仲裁队列来代替镜像集群,底层采用Raft协议确保主从的数据一致性。

二、普通集群搭建

1. 准备

建立如下文件夹结构

txt 复制代码
./cluster/
├── docker-compose.yml
├── mq1
│   ├── .erlang.cookie
│   └── conf
│       └── rabbitmq.conf
├── mq2
│   ├── .erlang.cookie
│   └── conf
│       └── rabbitmq.conf
└── mq3
    ├── .erlang.cookie
    └── conf
        └── rabbitmq.conf

2. 配置

rabbitmq.conf都写入以下内容

shell 复制代码
loopback_users.guest = false
listeners.tcp.default = 5672
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config
cluster_formation.classic_config.nodes.1 = rabbit@mq1
cluster_formation.classic_config.nodes.2 = rabbit@mq2
cluster_formation.classic_config.nodes.3 = rabbit@mq3
vm_memory_high_watermark.absolute = 524288000

.erlang.cookie都写入以下内容

txt 复制代码
SUGWXEQPRCPYJAVYPNZY

集群的所有节点的.erlang.cookie需要保持一致才能互相信任,具体内容并不固定,可以随便新建一个rabbitmq容器去查看其.erlang.cookie然后复制使用即可。

docker-compose.yml写入以下内容

yml 复制代码
version: "3.8"

networks:
  rabbitmq-normal-cluster:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.30.3.0/24

services:
  mq1:
    container_name: mq1
    hostname: mq1
    image: rabbitmq:3-management
    environment:
      - RABBITMQ_DEFAULT_USER=rabbitmq
      - RABBITMQ_DEFAULT_PASS=rabbitmq
    volumes:
      - ./mq1/conf/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
      - ./mq1/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie:ro
    ports:
      - "8071:5672"
      - "8081:15672"
    networks:
      rabbitmq-normal-cluster:
        ipv4_address: 172.30.3.11

  mq2:
    container_name: mq2
    hostname: mq2
    image: rabbitmq:3-management
    environment:
      - RABBITMQ_DEFAULT_USER=rabbitmq
      - RABBITMQ_DEFAULT_PASS=rabbitmq
    volumes:
      - ./mq2/conf/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
      - ./mq2/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie:ro
    ports:
      - "8072:5672"
      - "8082:15672"
    networks:
      rabbitmq-normal-cluster:
        ipv4_address: 172.30.3.12

  mq3:
    container_name: mq3
    hostname: mq3
    image: rabbitmq:3-management
    environment:
      - RABBITMQ_DEFAULT_USER=rabbitmq
      - RABBITMQ_DEFAULT_PASS=rabbitmq
    volumes:
      - ./mq3/conf/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
      - ./mq3/.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie:ro
    ports:
      - "8073:5672"
      - "8083:15672"
    networks:
      rabbitmq-normal-cluster:
        ipv4_address: 172.30.3.13

3. 运行

bash 复制代码
docker-compose -p rabbitmq-c up -d

三、镜像集群

1. 介绍

镜像模式的配置有3种模式:

ha-mode ha-params 效果
准确模式exactly 队列的副本量count 集群中队列副本(主服务器和镜像服务器之和)的数量。count如果为1意味着单个副本:即队列主节点。count值为2表示2个副本:1个队列主和1个队列镜像。换句话说:count = 镜像数量 + 1。如果群集中的节点数少于count,则该队列将镜像到所有节点。如果有集群总数大于count+1,并且包含镜像的节点出现故障,则将在另一个节点上创建一个新的镜像。
all (none) 队列在群集中的所有节点之间进行镜像。队列将镜像到任何新加入的节点。镜像到所有节点将对所有群集节点施加额外的压力,包括网络I / O,磁盘I / O和磁盘空间使用情况。推荐使用exactly,设置副本数为(N / 2 +1)。
nodes node names 指定队列创建到哪些节点,如果指定的节点全部不存在,则会出现异常。如果指定的节点在集群中存在,但是暂时不可用,会创建节点到当前客户端连接到的节点。

2. 启用方式

三种模式启动方式分别如下,基于普通集群之上,命令均需要在单个容器内部执行。

bash 复制代码
rabbitmqctl set_policy ha-two "^two\." '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
bash 复制代码
rabbitmqctl set_policy ha-all "^all\." '{"ha-mode":"all"}'
bash 复制代码
rabbitmqctl set_policy ha-nodes "^nodes\." '{"ha-mode":"nodes","ha-params":["rabbit@nodeA", "rabbit@nodeB"]}'

3. 测试

这里以exactly为例,在mq1中执行rabbitmqctl set_policy ha-two "^two\." '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'后,所有前缀为twoqueue都会有1个主queue和1个副本。

txt 复制代码
root@mq1:/# rabbitmqctl set_policy ha-two "^two\." '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
Setting policy "ha-two" for pattern "^two\." to "{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}" with priority "0" for vhost "/" ...
root@mq1:/# 

来到localhost:8081管理页,找到admin->policies可以看到策略生效。

来新建一个two.test.queue,可以看到这是一个拥有副本的queue

四、仲裁队列

1. 介绍

仲裁队列:仲裁队列是3.8版本以后才有的新功能,用来替代镜像队列,具备下列特征:

  • 与镜像队列一样,都是主从模式,支持主从数据同步
  • 使用非常简单,没有复杂的配置
  • 主从同步基于Raft协议,强一致

上一章中想要一个镜像队列还要执行各种命令,遵循规定,现在不用了。

2. 创建


java使用目前只能基于@Bean创建

java 复制代码
    @Bean
    public Queue quorumQueue(){
        return QueueBuilder
                .durable("quorum.queue2")
                .quorum()
                .build();
    }

五、Java连接RabbitMQ集群方式

Java使用RabbitMQ集群application.yml中需要修改address

yml 复制代码
spring:
  rabbitmq:
    host: localhost # rabbitMQ的ip地址
    port: 5672 # 端口
yml 复制代码
spring:
  rabbitmq:
	addresses: localhost:8071, localhost:8072, localhost:8073
相关推荐
初次攀爬者2 天前
RabbitMQ的消息模式和高级特性
后端·消息队列·rabbitmq
初次攀爬者4 天前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
让我上个超影吧5 天前
消息队列——RabbitMQ(高级)
java·rabbitmq
塔中妖5 天前
Windows 安装 RabbitMQ 详细教程(含 Erlang 环境配置)
windows·rabbitmq·erlang
断手当码农5 天前
Redis 实现分布式锁的三种方式
数据库·redis·分布式
初次攀爬者5 天前
Redis分布式锁实现的三种方式-基于setnx,lua脚本和Redisson
redis·分布式·后端
业精于勤_荒于稀5 天前
物流订单系统99.99%可用性全链路容灾体系落地操作手册
分布式
Ronin3055 天前
信道管理模块和异步线程模块
开发语言·c++·rabbitmq·异步线程·信道管理
Asher05095 天前
Hadoop核心技术与实战指南
大数据·hadoop·分布式
凉凉的知识库5 天前
Go中的零值与空值,你搞懂了么?
分布式·面试·go