MSMQ消息队列》》Rabbit MQ》》集群
将一台主机上的 .erlang.cookie 文件拷贝到其他两台主机上。该 cookie 文件相当于密钥令牌,集群中的 RabbitMQ 节点需要通过交换密钥令牌以获得相互认证,因此处于同一集群的所有节点需要具有相同的密钥令牌,否则在搭建过程中会出现 Authentication Fail 错误。相互通信,cookie必须保持一致,》》 拷贝 cookie。
普通集群
相互通信,cookie必须保持一致 同时要帮助 各个几点 互通 (/etc/host 追加各个节点 ip和 节点名称)
将一台主机上的 .erlang.cookie 文件拷贝到其他两台主机上。该 cookie 文件相当于密钥令牌,集群中的 RabbitMQ 节点需要通过交换密钥令牌以获得相互认证,
因此处于同一集群的所有节点需要具有相同的密钥令牌,否则在搭建过程中会出现 Authentication Fail 错误。




## RABIITMQ_NODENAME 命名规范
具体规则如下:
第一种:配置的名字里面加了@,那么 @后面必须要跟你的**主机名**(--hostname),否则启动会报错。这种情况启动后的节点名称就和你配置文件里面的名称一致
第二种:配置的名字里面没有@,那么启动后的的节点名称,mq会自动加上@+主机名,节点名称就是--配置名称+@+主机名


# 通常需要把三个rabbitmq,部署到不同的主机上。我这边部署到同一台计算机了 相互通信,cookie 名称必须保持一致,
# 创建共享网络
# 也可以设置 账号和密码
-e RABBITMQ_DEFAULT_USER=admin 设置默认用户名。
-e RABBITMQ_DEFAULT_PASS=admin 设置默认密码。
# 如果要设置 数据持久化
# 要在宿主机创建文件夹
>mkdir -p /home/middleware/rabbitmq/data
>mkdir -p /home/middleware/rabbitmq/logs
-v 宿主路径:rabbitmq的容器数据路径
-v /home/middleware/rabbitmq/data:/var/lib/rabbitmq \ # 挂载数据目录
-v /home/middleware/rabbitmq/logs:/var/log/rabbitmq \ # 挂载日志目录
docker network create rabbitnet
docker run -itd --rm --name rabbitmq_1 --network rabbitnet --hostname Node1 -e RABIITMQ_NODENAME=rabbit -e RABBITMQ_ERLANG_COOKIE='rabbitmq-cookie' -p 5571:5672 -p 15571:15672 rabbitmq:4-management
docker run -itd --rm --name rabbitmq_2 --network rabbitnet --hostname Node2 -e RABIITMQ_NODENAME=rabbit -e RABBITMQ_ERLANG_COOKIE='rabbitmq-cookie' -p 5572:5672 -p 15572:15672 rabbitmq:4-management
docker run -itd --rm --name rabbitmq_3 --network rabbitnet --hostname Node3 -e RABIITMQ_NODENAME=rabbit -e RABBITMQ_ERLANG_COOKIE='rabbitmq-cookie' -p 5573:5672 -p 15573:15672 rabbitmq:4-management
## 进去容器中 加入集群
docker exec -it 容器名称 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@节点名称
rabbitmqctl start_app


》》查看三个容器的IP信息
docker inspect 容器ID|容器名称
docker inspect rabbitmq_2

》》》补偿一个知识 docker cp 可以实现 本地和容器之间 互传文件 cookie 要一致



通过 docker compose 实现
要在宿主机创建文件夹
mkdir -p /home/middleware/rabbitmq/data
mkdir -p /home/middleware/rabbitmq/logs
services:
rabbitmqA:
container_name: rabbitmq-Container-A
image: rabbitmq:4-management
hostname: Node1
ports:
- 5571:5672
- 15571:15672
volumes:
- /home/middleware/rabbitmq/data:/var/lib/rabbitmq # 挂载数据目录
- /home/middleware/rabbitmq/logs:/var/log/rabbitmq # 挂载日志目录
environment:
- RABBITMQ_ERLANG_COOKIE=ZEN
- RABBITMQ_NODENAME=rabbit@Node1
- RABBITMQ_DEFAULT_VHOST=Zen_vhost
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=admin
rabbitmqB:
container_name: rabbitmq-Container-B
image: rabbitmq:4-management
hostname: Node2
ports:
- 5572:5672
- 15572:15672
volumes:
- /home/middleware/rabbitmq/data:/var/lib/rabbitmq # 挂载数据目录
- /home/middleware/rabbitmq/logs:/var/log/rabbitmq # 挂载日志目录
environment:
- RABBITMQ_ERLANG_COOKIE=ZEN
- RABBITMQ_NODENAME=rabbit@Node2
- RABBITMQ_DEFAULT_VHOST=Zen_vhost
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=admin
rabbitmqC:
container_name: rabbitmq-Container-C
image: rabbitmq:4-management
hostname: Node3
volumes:
- /home/middleware/rabbitmq/data:/var/lib/rabbitmq # 挂载数据目录
- /home/middleware/rabbitmq/logs:/var/log/rabbitmq # 挂载日志目录
ports:
- 5573:5672
- 15573:15672
environment:
- RABBITMQ_ERLANG_COOKIE=ZEN
- RABBITMQ_NODENAME=rabbit@Node3
- RABBITMQ_DEFAULT_VHOST=Zen_vhost
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=admin


## 进去容器中 加入集群
docker exec -it 容器名称 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@节点名称
rabbitmqctl start_app

镜像队列集群 镜像集群模式(高可用性) 3.* 版本支持,4.X 版本取消了。
不知道为啥 我的rabbitmq中没有HA-mode, 命令行添加也不行。
这种模式,才是所谓的 RabbitMQ 的高可用模式。跟普通集群模式不一样的是,在镜像集群模式下,你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,就是说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像,包含 queue 的全部数据的意思。然后每次你写消息到 queue 的时候,都会自动把消息同步到多个实例的 queue 上。



rabbitmqctl set_policy -p Zen_vhost --priority 1 --apply-to all myPolicy “^zen.*” ‘{“ha-mode”:“all”}’


C#驱动RabbitMQ集群
C#驱动RabbitMQ集群与C#驱动单机RabbtiMQ的方式基本一样,区别在于使用集群时,创建Connection指定的是一个host集合。看一个简单
# 生产者 ,消费者 只需要连接时,如下配置即可
//集群中的三个rabbitmq节点
List<string> hosts = new List<string>() { "192.168.70.129", "192.168.70.131", "192.168.70.1233" };
//随机连接一个rabbitmq节点
using var connection = await factory.CreateConnectionAsync(hosts);
##
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;
namespace RabbitMQ_Consumer
{
internal class Program
{
internal class Program
{
static void Main(string[] args)
{
Producer();
Console.ReadLine();
}
static async void Producer()
{
var factory = new ConnectionFactory
{
HostName = "172.XX.XX.x6",
Port = 5672,
UserName = "guest",
Password = "guest"
};
//集群中的三个rabbitmq节点
List<string> hosts = new List<string>() { "192.168.70.129", "192.168.70.131", "192.168.70.1233" };
//随机连接一个rabbitmq节点
using var connection = await factory.CreateConnectionAsync(hosts);
using var channel = await connection.CreateChannelAsync();
await channel.QueueDeclareAsync("hello", durable: false, exclusive: false, autoDelete: false, arguments: null);
for (int i = 0; i < 100; i++)
{
var message = $"[消息{i}] Hello World";
var body = Encoding.UTF8.GetBytes(message);
await channel.BasicPublishAsync(exchange: "", routingKey: "hello", body: body);
Console.WriteLine($"消息:{message} 已发送");
}
}
}
}
更多推荐



所有评论(0)