容器化运维:构建高可用RabbitMQ集群的Docker Compose指南
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
容器化运维构建高可用RabbitMQ集群的Docker Compose指南
前言
在计算机世界中消息传递就像是一场神奇的旅行消息在系统之间飞来飞去就像是魔法传送一样。而今天我们将进入一个充满奇幻冒险的领域——RabbitMQ集群的实现。
想象一下RabbitMQ就是我们的信使兔子它们不仅聪明灵活还能够把消息从一个地方快速传递到另一个地方。而RabbitMQ集群就像是一支强大的兔子家族它们紧密合作确保消息永远不会丢失就像是一场兔子魔法秀。
在这个奇幻的旅程中我们将揭开RabbitMQ集群的面纱一起探索如何构建一个强大的消息传递系统它能够应对高负载、容错性强就像是一支无所不能的魔法军团。
所以准备好跟随我们的兔子朋友踏上这段有趣而充满挑战的消息传递冒险吧在这个奇妙的世界里你将发现消息传递的魔法是无穷无尽的。
对于RabbitMQ可以先进行几个知识点的讲解
RabbitMQ相关知识点
❓Exchanges中的类型有什么区别
-
Direct Exchange直连交换器
- 根据消息的 routing key路由键将消息发送到与之完全匹配的队列。
- 只有当消息的路由键与绑定到交换器的队列的路由键完全匹配时消息会被发送到该队列。
- 适用于需要精确匹配路由键的情况。
-
Topic Exchange主题交换器
- 使用通配符匹配消息的路由键与绑定的队列。
- 可以使用通配符 “*”匹配一个单词和 “#”匹配多个单词来定义路由键的模式。
- 适用于需要灵活匹配路由键的情况支持复杂的消息路由。
-
Fanout Exchange扇出交换器
- 将接收到的消息广播到绑定的所有队列忽略消息的路由键。
- 所有绑定到交换器的队列都会接收相同的消息副本。
- 适用于需要消息广播到所有队列的情况。
-
Headers Exchange头交换器
- 使用消息的头部属性进行匹配而不是使用路由键。
- 你可以在消息的头部设置键值对属性然后通过绑定队列时设置匹配的头部属性。
- 适用于基于消息头部属性进行路由的情况。
选择合适的交换器类型取决于你的应用架构和消息传递需求。通常情况下使用直连交换器和主题交换器可以满足大多数场景。如果你需要在多个队列之间广播消息可以使用扇出交换器。如果需要基于消息头部属性进行匹配可以使用头交换器。
要注意的是交换器类型一旦设置后通常是不可更改的。因此在选择交换器类型时需要根据实际需求进行权衡和规划。
❓policies是什么
在 RabbitMQ 中“policies”策略是一种机制用于自动化管理和配置交换器、队列和绑定的行为。策略允许你在 RabbitMQ 集群中定义一组规则这些规则会自动应用于交换器、队列和绑定从而在满足特定条件时执行预定义的操作。这样可以简化管理、提高效率并确保一致性。
策略可以用于许多方面包括队列的镜像、过期时间、消息最大长度、死信队列等。通过设置策略你可以在集群中的多个节点上自动应用相同的配置而不需要手动进行每个节点的配置更改。
以下是一些策略的常见作用
-
镜像队列策略 允许你在队列声明时自动将队列设置为镜像队列从而实现消息冗余备份和高可用性。
-
队列过期策略 允许你设置队列中的消息的过期时间当消息过期时RabbitMQ 会自动将其从队列中删除。
-
消息最大长度策略 允许你限制队列中消息的最大长度当队列中的消息数量达到设置的最大长度时新的消息将被丢弃或处理为死信。
-
死信队列策略 允许你将队列中无法被消费的消息自动发送到死信队列以便进一步处理。
-
优先级队列策略 允许你为消息设置优先级并根据优先级将消息放入不同的队列中。
等等。
要设置策略你可以使用 RabbitMQ Management 插件的管理界面也可以使用命令行工具如 rabbitmqctl
。通过设置策略你可以实现自动化管理和配置减少手动操作的需要提高系统的可靠性和可维护性。
❓策略如何设置
参数说明
-
Pattern匹配模式
- 这是一个用于匹配交换器、队列和绑定的模式。可以使用通配符
*
和#
。 - 例如你可以使用
amq.*
匹配所有以amq.
开头的交换器。
- 这是一个用于匹配交换器、队列和绑定的模式。可以使用通配符
-
Definition定义
- 这是一个包含策略定义的 JSON 对象。具体的参数和值取决于你想要配置的策略类型。
- 例如如果要创建一个镜像队列策略可以定义
ha-mode
和其他相关参数。
-
ha-mode镜像队列模式
- 用法
ha-mode = all
或ha-mode = exactly
或ha-mode = nodes
- 作用定义队列是否为镜像队列从而实现消息冗余备份和高可用性。
all
将队列设置为镜像队列在所有节点上创建队列的镜像。exactly
将队列设置为镜像队列并指定要创建的镜像节点数量。nodes
将队列设置为镜像队列指定要在哪些节点上创建镜像。
- 用法
-
ha-params镜像队列参数
- 用法
ha-params = ["node1", "node2"]
- 作用用于
ha-mode = nodes
指定创建队列镜像的节点列表。
- 用法
-
expires消息过期时间
- 用法
expires = 3600000
毫秒 - 作用定义队列中消息的过期时间过期的消息将被自动删除。
- 用法
-
message-ttl消息存活时间
- 用法
message-ttl = 60000
毫秒 - 作用定义消息在队列中的存活时间超过该时间的消息将被自动删除。
- 用法
-
max-length最大消息数量
- 用法
max-length = 1000
- 作用限制队列中消息的最大数量当队列中的消息数量达到指定值时新的消息将被丢弃或处理为死信。
- 用法
-
dead-letter-exchange死信交换器
- 用法
dead-letter-exchange = dlx_exchange
- 作用指定死信队列中的消息应该发送到的交换器。
- 用法
-
dead-letter-routing-key死信路由键
- 用法
dead-letter-routing-key = dlx_routing_key
- 作用指定死信队列中的消息应该使用的路由键。
- 用法
-
max-length-bytes最大消息字节数
- 用法
max-length-bytes = 102400
- 作用限制队列中消息的总字节数当队列中消息的总字节数达到指定值时新的消息将被丢弃或处理为死信。
- 用法
-
lazy-mode延迟模式
- 用法
lazy-mode = on
或lazy-mode = off
- 作用启用或禁用延迟模式用于将队列中的消息保存到磁盘以降低内存使用。
- 用法
-
queue-mode队列模式
- 用法
queue-mode = lazy
或queue-mode = default
- 作用定义队列的工作模式
lazy
表示延迟模式default
表示默认模式。
- 用法
-
Priority优先级
- 用于指定策略的优先级当有多个策略匹配时优先级较高的策略会覆盖较低的策略。
- 优先级通常使用整数表示值越小表示优先级越高。
-
Apply to应用于
- 用于指定策略应该应用于哪些对象交换器、队列、绑定。
- 可以选择 “exchanges”、“queues” 或 “all”。
之所以说上面的东西主要是为了实现我们的集群也就是我添加的策略因为如果单独创建队列的话它是默认只属于当前的节点的所以需要依靠镜像或者说这种策略实现
docker-compose 搭建RabbitMQ的集群
创建docker-compose.yml文件
version: '3'
services:
rabbitmq-node1:
image: rabbitmq:3.9.22-management
container_name: rabbitmq-node1
hostname: rabbitmq-node1
# command: rabbitmq-server --erlang-cookie=97c78681-3394-208f-9d04-b86cb68f9c60
entrypoint: /bin/bash -c "rabbitmq-server rabbitmqctl wait /var/lib/rabbitmq/mnesia/rabbit@rabbitmq-node1.pid"
ports:
- "5672:5672"
- "15672:15672"
volumes:
- ./rabbitmq_delayed_message_exchange-3.9.0.ez:/plugins/rabbitmq_delayed_message_exchange-3.9.0.ez
- ./.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie
- ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
environment:
- RABBITMQ_DELAYED_MESSAGE_ENABLED=true
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=123456
- RABBITMQ_PLUGINS=--offline rabbitmq_delayed_message_exchange
- RABBITMQ_NODENAME=rabbit@rabbitmq-node1 # 节点名称
# - RABBITMQ_USE_LONGNAME=true #它用于告诉 RabbitMQ 是否使用长节点名称。
networks:
- rabbitmq-network
rabbitmq-node2:
image: rabbitmq:3.9.22-management
container_name: rabbitmq-node2
hostname: rabbitmq-node2
entrypoint: /bin/bash -c "rabbitmq-server rabbitmqctl wait /var/lib/rabbitmq/mnesia/rabbit@rabbitmq-node2.pid && rabbitmqctl join_cluster rabbit@rabbitmq-node1"
# command: rabbitmq-server --erlang-cookie=97c78681-3394-208f-9d04-b86cb68f9c60
ports:
- "5673:5672"
- "15673:15672"
volumes:
- ./rabbitmq_delayed_message_exchange-3.9.0.ez:/plugins/rabbitmq_delayed_message_exchange-3.9.0.ez
- ./.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie
- ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
environment:
- RABBITMQ_DELAYED_MESSAGE_ENABLED=true
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=123456
- RABBITMQ_PLUGINS=--offline rabbitmq_delayed_message_exchange
- RABBITMQ_NODENAME=rabbit@rabbitmq-node2 # 节点名称
# - RABBITMQ_USE_LONGNAME=true #它用于告诉 RabbitMQ 是否使用长节点名称。
networks:
- rabbitmq-network
depends_on:
- rabbitmq-node1
rabbitmq-node3:
image: rabbitmq:3.9.22-management
container_name: rabbitmq-node3
hostname: rabbitmq-node3
# command: rabbitmq-server --erlang-cookie=97c78681-3394-208f-9d04-b86cb68f9c60
entrypoint: /bin/bash -c "rabbitmq-server rabbitmqctl wait /var/lib/rabbitmq/mnesia/rabbit@rabbitmq-node3.pid && rabbitmqctl join_cluster rabbit@rabbitmq-node1"
ports:
- "5674:5672"
- "15674:15672"
volumes:
- ./rabbitmq_delayed_message_exchange-3.9.0.ez:/plugins/rabbitmq_delayed_message_exchange-3.9.0.ez
- ./.erlang.cookie:/var/lib/rabbitmq/.erlang.cookie
- ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
environment:
- RABBITMQ_DELAYED_MESSAGE_ENABLED=true
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=123456
- RABBITMQ_PLUGINS=--offline rabbitmq_delayed_message_exchange
#被废弃了 - RABBITMQ_ERLANG_COOKIE=97c78681-3394-208f-9d04-b86cb68f9c60 # 为了确保集群节点通信需要设置相同的 erlang-cookie
- RABBITMQ_NODENAME=rabbit@rabbitmq-node3 # 节点名称
# - RABBITMQ_USE_LONGNAME=true #它用于告诉 RabbitMQ 是否使用长节点名称。
networks:
- rabbitmq-network
depends_on:
- rabbitmq-node1
networks:
rabbitmq-network:
driver: bridge
⚠这里使用的挂载第一个是实现的延迟队列插件第二个是挂载所需的cookie
这个cookie
可以是任意的第三个是配置文件
上面部分语句说明如下
entrypoint: /bin/bash -c "rabbitmq-server rabbitmqctl wait /var/lib/rabbitmq/mnesia/rabbit@rabbitmq-node3.pid && rabbitmqctl join_cluster rabbit@rabbitmq-node1"
等待并加入集群RABBITMQ_PLUGINS=--offline rabbitmq_delayed_message_exchange
指定要加载的插件且加载预先下载好的RABBITMQ_DELAYED_MESSAGE_ENABLED=true
启动消息延迟功能
创建rabbitmq.conf文件
# 配置内容
# 这个配置的作用是禁用 "guest" 用户对本地loopback的访问。
loopback_users.guest = false
listeners.tcp.default = 5672
# 这个配置指定了集群节点之间的发现机制。`rabbit_peer_discovery_classic_config` 表示使用经典配置方式来进行节点发现。
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config
# 这个配置指定了集群中的节点`rabbit@rabbitmq-node1` 表示第一个节点的名称和主机地址。
cluster_formation.classic_config.nodes.1 = rabbit@rabbitmq-node1
cluster_formation.classic_config.nodes.2 = rabbit@rabbitmq-node2
cluster_formation.classic_config.nodes.3 = rabbit@rabbitmq-node3
⚠上面的文件要处于同级目录
项目中如何实现集群连接
如果是实现集群连接的话这个在go与java中还是有所不同的但是我们可以是用nginx来做一下负载均衡来实现或者说RabbitMQ它也有自己的实现
⚠nginx模块中需要添加stream模块才可以实现和连接mysql是一样的
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |