【RabbitMQ 集群企业级实战:RabbitMQ 特性、存储、工作模式解析与普通集群搭建及仲裁队列搭建企业级配置】

提示:本文原创作品,良心制作,干货为主,简洁清晰,一看就会

文章目录

  • 一、消息中间件
    • [1.1 什么是消息中间件](#1.1 什么是消息中间件)
    • [1.2 消息中间件的作用](#1.2 消息中间件的作用)
    • [1.3 消息中间件的两种模式](#1.3 消息中间件的两种模式)
    • [1.4 常用的消息中间件](#1.4 常用的消息中间件)
  • 二、RabbitMQ集群
    • [2.1 rabbitmq是什么](#2.1 rabbitmq是什么)
    • [2.2 rabbitmq特点](#2.2 rabbitmq特点)
    • [2.3 数据存储方式](#2.3 数据存储方式)
    • [2.4 rabbitmq模式](#2.4 rabbitmq模式)
    • [2.5 rabbitmq集群企业级实战](#2.5 rabbitmq集群企业级实战)
      • [2.5.1 环境介绍](#2.5.1 环境介绍)
      • [2.5.2 配置解析](#2.5.2 配置解析)
      • [2.5.3 下载erlang,rabbitmq](#2.5.3 下载erlang,rabbitmq)
      • [2.5.4 添加rabbitmq-2,rabbitmq-3](#2.5.4 添加rabbitmq-2,rabbitmq-3)
      • [2.5.5 rabbitmq仲裁队列配置](#2.5.5 rabbitmq仲裁队列配置)

一、消息中间件

1.1 什么是消息中间件

消息中间件也可以称消息队列,是指用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成

通过提供消息传递和消息队列模型,可以在分布式环境下扩展进程的通信

1.2 消息中间件的作用

消息中间件是分布式系统和微服务架构中的关键基础组件,其核心作用是解耦、异步、削峰、可靠传输、流量控制与数据同步,帮助系统提升可用性、扩展性和稳定性,具体作用如下:

应用解耦,降低系统耦合度

消息中间件可以让服务之间不再直接依赖和调用,而是通过消息进行通信

实现异步处理,提升系统响应速度

业务系统只需将任务封装为消息发送到队列,即可立即返回结果给用户,后续由消费者异步处理

流量削峰填谷,保护核心系统

在秒杀、抢购、订单峰值、日志爆发等场景下,瞬时流量可能远超系统承载能力,直接冲击数据库和核心服务,导致服务崩溃

消息中间件作为流量缓冲层,可将瞬间暴涨的请求暂存到队列中,让后端消费者按照自身处理能力匀速消费,避免流量直接压垮下游系统。通过削峰填谷,平滑流量波动,保证系统在高并发场景下稳定运行

保证消息可靠传输,防止数据丢失

消息发送后可持久化存储到磁盘,即使服务重启、宕机,消息也不会丢失;通过生产者确认、消费者应答机制,确保消息至少被成功消费一次

1.3 消息中间件的两种模式

消息中间件主流分为点对点模式和发布/订阅模式两种核心通信模型

点对点(P2P)模式

P2P模式包含三个角色:消息队列(Queue)、发送者(Sender)、接收者(Receiver)。每个消息都被发送到一个特定的队列,接收者从队列中获取消息;队列保留着消息,直到它们被消费或超时

特点

1,不可重复消费,每个消息只有一个消费者,即一旦被消费,消息就不再在消息队列中存在

2,发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行它不会影响到消息被发送到队列

3,接收者在成功接收消息之后需向队列应答成功

4,如果希望发送的每个消息都会被成功处理的话,那么需要P2P模式

发布/订阅(Pub/Sub)模式

Pub/Sub模式包含三个角色:话题(Topic)、发布者(Publisher)、订阅者(Subscriber);多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者

特点

1,可重复消费,每个消息可以有多个消费者

2,发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息

3,为了消费消息,订阅者必须保持运行的状态

4,如果希望发送的消息可以不被做任何处理、或者只被一个消费者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型

1.4 常用的消息中间件

RabbitMQ 是基于 Erlang 语言开发的开源消息队列,遵循 AMQP 协议,具备轻量、稳定、延迟低的特点,AMQP协议更多用在企业系统内对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次

Kafka 是LinkedIn开源的分布式发布-订阅消息系统,主要特点是追求高吞吐量,一开始的目的就是用于日志收集和传输。不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量日志数据的互联网服务的数据收集业务

想了解 Kafka 与日志结合的企业级实践,可以参考我这篇文章https://blog.csdn.net/m0_63756214/article/details/157254529?spm=1001.2014.3001.5501

RocketMQ 是阿里开源的分布式消息中间件,专为高并发、高可用金融级场景设计,支持严格的消息顺序性与事务消息,在电商交易、支付结算等对可靠性要求极高的场景中应用广泛

ActiveMQ 等传统消息中间件,虽然性能与扩展性相对较弱,但在传统企业项目中仍有一定应用

二、RabbitMQ集群

2.1 rabbitmq是什么

RabbitMQ 是一款基于 Erlang 语言开发的开源消息中间件,遵循 AMQP 高级消息队列协议,是轻量级、高可用的分布式消息通信组件。它核心实现了消息的生产、存储、路由与消费,能在分布式系统中实现服务间异步通信,解耦上下游业务

2.2 rabbitmq特点

1、遵循 AMQP 协议,跨语言、跨平台兼容性强,支持 Java、Python、Go 等主流开发语言

2、架构灵活,支持复杂消息路由策略

3、可靠性高,支持消息持久化、生产者确认、消费者应答,可有效防止数据丢失

4、轻量级部署,资源占用低

5、提供可视化管理界面,便于运维监控和操作

2.3 数据存储方式

RabbitMQ从 3.12 开始弃用 "磁盘节点 / 内存节点" 的显式区分,默认启用 Khepri 分布式数据库引擎,所有节点的存储逻辑由 Khepri 自动管理,无需人工指定节点类型;

数据到底存在磁盘还是内存?

Khepri 采用「混合存储 + 智能缓存」的策略,而非简单的 "只存磁盘" 或 "只存内存"

1,核心元数据(集群配置、队列元信息、用户权限等)

持久化到磁盘:默认存储在 /var/lib/rabbitmq/mnesia/

内存缓存:同时会加载到内存中,保证集群节点间的快速同步和访问

2,消息数据(队列里的消息)

持久化消息:先写入内存缓存,再异步刷到磁盘(/var/lib/rabbitmq/),重启后可恢复

非持久化消息:仅存在内存中,节点重启后丢失(和旧版本逻辑一致)

2.4 rabbitmq模式

RabbitMQ提供三种核心集群部署模式,适配不同可用性、可靠性需求的业务场景:

单机模式

单机模式是最基础的部署形态,适合开发测试、小型非核心业务场景,但无任何高可用保障

普通模式(默认集群模式)

普通模式是RabbitMQ默认的集群部署方式,多个节点组成集群但数据仅做部分共享:交换机、绑定关系等元数据在集群节点间同步,而队列数据仅存储在创建该队列的节点上,其他节点仅保存队列的访问引用。该模式存储队列数据的节点故障后,该队列无法访问

仲裁模式(HA高可用模式)

RabbitMQ 4.0+ 已完全移除镜像队列(ha-mode 等配置彻底失效),官方将仲裁队列作为唯一的高可用队列实现,其核心是基于 Raft 分布式一致性协议 管理队列副本

  • 每个仲裁队列会在集群中创建 N 个副本(默认 3 个,可自定义),分布在不同节点;
  • 副本分为领导者(Leader)」和「跟随者(Follower)」
  • 生产者 / 消费者仅与 Leader 交互,保证写入 / 读取的一致性
  • Follower 实时同步 Leader 的数据,Leader 故障时,Raft 协议会自动选举新的 Leader(秒级完成)
  • 只要副本数量的 半数以上节点在线(比如 3 个副本至少 2 个在线),队列就能正常提供服务(这也是 "仲裁" 的含义)

2.5 rabbitmq集群企业级实战

2.5.1 环境介绍

实验前先关闭防火墙或开启相应端口,RabbitMQ集群节点必须在同一网段,如果是跨域,效果会变差

主机名 ip
rabbitmq-1 192.168.136.140
rabbitmq-2 192.168.136.141
rabbitmq-3 192.168.136.142

RabbitMQ 集群运行依赖的端口:

端口号 用途说明
5672 AMQP 协议端口(客户端连接),开发向我们要的一般是这个接口
15672 Web 管理界面端口(可选,便于运维)
25672 Erlang 分布式通信端口(集群节点间通信核心)
4369 EPMD 端口(Erlang 端口映射守护进程,集群必需)

2.5.2 配置解析

bash 复制代码
#给每个机器的/etc/hosts中都配置好解析
root@rabbitmq-1:~# vim /etc/hosts
192.168.136.140 rabbitmq-1
192.168.136.141 rabbitmq-2
192.168.136.142 rabbitmq-3

2.5.3 下载erlang,rabbitmq

Rabbitmq官网:https://www.rabbitmq.com/docs/which-erlang

根据自己的系统选择相应的安装指南

选择适合自己系统的安装脚本

bash 复制代码
#官网直接复制脚本,三台机器同样操作
root@rabbitmq-1:~# vim rabbitmq.sh
#!/bin/sh

## 安装脚本后续需要的基础工具
sudo apt-get install curl gnupg apt-transport-https -y

## 导入 RabbitMQ 官方的 GPG 公钥,解决 "安装包签名验证失败" 问题
curl -1sLf "https://keys.openpgp.org/vks/v1/by-fingerprint/0A9AF2115F4687BD29803A206B73A36E6026DFCA" | sudo gpg --dearmor | sudo tee /usr/share/keyrings/com.rabbitmq.team.gpg > /dev/null

## 向系统添加 RabbitMQ 官方维护的两个软件源(解决 Ubuntu 官方源 Erlang 版本不匹配问题)
sudo tee /etc/apt/sources.list.d/rabbitmq.list <<EOF
## 提供与 RabbitMQ 严格兼容的 Erlang 版本
##
deb [arch=amd64 signed-by=/usr/share/keyrings/com.rabbitmq.team.gpg] https://deb1.rabbitmq.com/rabbitmq-erlang/ubuntu/jammy jammy main
deb [arch=amd64 signed-by=/usr/share/keyrings/com.rabbitmq.team.gpg] https://deb2.rabbitmq.com/rabbitmq-erlang/ubuntu/jammy jammy main

## 提供最新稳定版 RabbitMQ 安装包
##
deb [arch=amd64 signed-by=/usr/share/keyrings/com.rabbitmq.team.gpg] https://deb1.rabbitmq.com/rabbitmq-server/ubuntu/jammy jammy main
deb [arch=amd64 signed-by=/usr/share/keyrings/com.rabbitmq.team.gpg] https://deb2.rabbitmq.com/rabbitmq-server/ubuntu/jammy jammy main
EOF

## 更新 apt 源缓存(让系统识别新源)
sudo apt-get update -y

## 安装 RabbitMQ 运行依赖的所有 Erlang 组件
sudo apt-get install -y erlang-base \
                        erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \
                        erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
                        erlang-runtime-tools erlang-snmp erlang-ssl \
                        erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl

## 安装 RabbitMQ 主程序,并自动修复缺失的依赖
sudo apt-get install rabbitmq-server -y --fix-missing
bash 复制代码
#三台机器同样操作
root@rabbitmq-1:~# bash rabbitmq.sh   #执行脚本
root@rabbitmq-1:~# rabbitmq-plugins enable rabbitmq_management  # web管理插件默认不启动,我们手动打开
root@rabbitmq-1:~# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:15672           0.0.0.0:*               LISTEN      8023/beam.smp       
tcp        0      0 0.0.0.0:25672           0.0.0.0:*               LISTEN      8023/beam.smp       
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      848/systemd-resolve 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      901/sshd: /usr/sbin 
tcp6       0      0 :::5672                 :::*                    LISTEN      8023/beam.smp       
tcp6       0      0 :::4369                 :::*                    LISTEN      1/init              
tcp6       0      0 :::22                   :::*                    LISTEN      901/sshd: /usr/sbin 
root@rabbitmq-1:~# erl  #测试erlang是否安装成功
Erlang/OTP 27 [erts-15.2.7.4] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]

Eshell V15.2.7.4 (press Ctrl+G to abort, type help(). for help)
1>   ##出现版本表示安装成功,两次CTRL+c退出
root@rabbitmq-1:~# rabbitmqctl version   #rabbitmq版本
4.2.3
bash 复制代码
#RabbitMQ 默认的 guest 用户仅允许本地访问,需创建新的管理员用户才能远程登录:
root@rabbitmq-1:~# rabbitmqctl add_user admin 123456  #添加用户和密码
root@rabbitmq-1:~# rabbitmqctl set_user_tags admin administrator  #设置为管理员
root@rabbitmq-1:~# rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"  #给admin用户授予 / 虚拟主机的所有配置权限、所有写权限、所有读权限
root@rabbitmq-1:~# rabbitmqctl list_users   #查看有哪些用户
Listing users ...
user    tags
admin   [administrator]
guest   [administrator]
root@rabbitmq-1:~# 

浏览器访问ip:15672就可以登录Web管理界面

至此,rabbitmq集群普通模式搭建成功

2.5.4 添加rabbitmq-2,rabbitmq-3

Rabbitmq的集群是依附于erlang的集群来工作的,所以必须先构建起erlang的集群

Erlang的集群中各节点是经由各个cookie来实现的,这个cookie存放在/var/lib/rabbitmq/.erlang.cookie中,文件是400的权限。所以必须保证各节点cookie一致,不然节点之间就无法通信

bash 复制代码
root@rabbitmq-1:~# ll /var/lib/rabbitmq/.erlang.cookie 
-r-------- 1 rabbitmq rabbitmq 20 Jan 26 00:00 /var/lib/rabbitmq/.erlang.cookie
root@rabbitmq-1:~# cat /var/lib/rabbitmq/.erlang.cookie
RIQAUVZNIWWYZHQGFQAX
root@rabbitmq-1:~# rabbitmqctl cluster_status   #查看集群状态
Cluster status of node rabbit@rabbitmq-1 ...
Basics

Cluster name: rabbit@rabbitmq-1
Disk Nodes

rabbit@rabbitmq-1

Running Nodes

rabbit@rabbitmq-1

#修改rabbitmq-2,上/var/lib/rabbitmq/.erlang.cookie中的内容,rabbitmq-3同样操作
root@rabbitmq-2:~# vim /var/lib/rabbitmq/.erlang.cookie
RIQAUVZNIWWYZHQGFQAX
root@rabbitmq-2:~# systemctl restart rabbitmq-server.service 
root@rabbitmq-2:~# rabbitmqctl stop_app  #停止节点
root@rabbitmq-2:~# rabbitmqctl reset    #如果有数据需要重置,没有则不用
root@rabbitmq-2:~# rabbitmqctl join_cluster rabbit@rabbitmq-1   #添加到集群中
root@rabbitmq-1:~# rabbitmqctl cluster_status   #查看集群状态
Cluster status of node rabbit@rabbitmq-1 ...
Basics

Cluster name: rabbit@rabbitmq-1
Disk Nodes

rabbit@rabbitmq-1
rabbit@rabbitmq-2
rabbit@rabbitmq-3

Running Nodes

rabbit@rabbitmq-1
rabbit@rabbitmq-2
rabbit@rabbitmq-3

浏览器访问ip:15672就可以登录Web管理界面

2.5.5 rabbitmq仲裁队列配置

仲裁模式是RabbitMQ的高可用解决方案,需基于普通集群模式搭建,普通集群不保证队列的高可用性,队列内容不会复制。如果队列节点宕机直接导致该队列无法应用,只能等待重启,所以要想在队列节点宕机或故障也能正常应用,就要复制队列内容到集群里的每个节点,必须要创建仲裁队列

bash 复制代码
#在普通模式集群中随便找一台机器
#从本地管理插件接口下载 rabbitmqadmin
root@rabbitmq-1:~# wget -O /usr/local/bin/rabbitmqadmin http://127.0.0.1:15672/cli/rabbitmqadmin
root@rabbitmq-1:~# chmod +x /usr/local/bin/rabbitmqadmin
root@rabbitmq-1:~# rabbitmqadmin --version
rabbitmqadmin 4.2.3
#创建名为test_queue的高可用队列
root@rabbitmq-1:~# rabbitmqadmin declare queue name=test_queue arguments='{"x-queue-type":"quorum"}'  
queue declared

浏览器访问ip:15672

至此,rabbitmq高可用模式搭建成功


注:

文中若有疏漏,欢迎大家指正赐教。

本文为100%原创,转载请务必标注原创作者,尊重劳动成果。

求赞、求关注、求评论!你的支持是我更新的最大动力,评论区等你~

相关推荐
初次攀爬者1 天前
RabbitMQ的消息模式和高级特性
后端·消息队列·rabbitmq
初次攀爬者3 天前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
让我上个超影吧4 天前
消息队列——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