容器化运维:构建高可用RabbitMQ集群的Docker Compose指南

简介: 容器化运维:构建高可用RabbitMQ集群的Docker Compose指南


前言

在计算机世界中,消息传递就像是一场神奇的旅行,消息在系统之间飞来飞去,就像是魔法传送一样。而今天,我们将进入一个充满奇幻冒险的领域——RabbitMQ集群的实现。

想象一下,RabbitMQ就是我们的信使兔子,它们不仅聪明灵活,还能够把消息从一个地方快速传递到另一个地方。而RabbitMQ集群就像是一支强大的兔子家族,它们紧密合作,确保消息永远不会丢失,就像是一场兔子魔法秀。

在这个奇幻的旅程中,我们将揭开RabbitMQ集群的面纱,一起探索如何构建一个强大的消息传递系统,它能够应对高负载、容错性强,就像是一支无所不能的魔法军团。

所以,准备好跟随我们的兔子朋友,踏上这段有趣而充满挑战的消息传递冒险吧!在这个奇妙的世界里,你将发现消息传递的魔法是无穷无尽的。

对于RabbitMQ可以先进行几个知识点的讲解

RabbitMQ相关知识点

❓:Exchanges中的类型有什么区别

  1. Direct Exchange(直连交换器):
  • 根据消息的 routing key(路由键)将消息发送到与之完全匹配的队列。
  • 只有当消息的路由键与绑定到交换器的队列的路由键完全匹配时,消息会被发送到该队列。
  • 适用于需要精确匹配路由键的情况。
  1. Topic Exchange(主题交换器):
  • 使用通配符匹配消息的路由键与绑定的队列。
  • 可以使用通配符 “*”(匹配一个单词)和 “#”(匹配多个单词)来定义路由键的模式。
  • 适用于需要灵活匹配路由键的情况,支持复杂的消息路由。
  1. Fanout Exchange(扇出交换器):
  • 将接收到的消息广播到绑定的所有队列,忽略消息的路由键。
  • 所有绑定到交换器的队列都会接收相同的消息副本。
  • 适用于需要消息广播到所有队列的情况。
  1. Headers Exchange(头交换器):
  • 使用消息的头部属性进行匹配,而不是使用路由键。
  • 你可以在消息的头部设置键值对属性,然后通过绑定队列时设置匹配的头部属性。
  • 适用于基于消息头部属性进行路由的情况。

选择合适的交换器类型取决于你的应用架构和消息传递需求。通常情况下,使用直连交换器和主题交换器可以满足大多数场景。如果你需要在多个队列之间广播消息,可以使用扇出交换器。如果需要基于消息头部属性进行匹配,可以使用头交换器。

要注意的是,交换器类型一旦设置后,通常是不可更改的。因此,在选择交换器类型时需要根据实际需求进行权衡和规划。

❓:policies是什么

在 RabbitMQ 中,“policies”(策略)是一种机制,用于自动化管理和配置交换器、队列和绑定的行为。策略允许你在 RabbitMQ 集群中定义一组规则,这些规则会自动应用于交换器、队列和绑定,从而在满足特定条件时执行预定义的操作。这样可以简化管理、提高效率,并确保一致性。

策略可以用于许多方面,包括队列的镜像、过期时间、消息最大长度、死信队列等。通过设置策略,你可以在集群中的多个节点上自动应用相同的配置,而不需要手动进行每个节点的配置更改。

以下是一些策略的常见作用:

  1. 镜像队列策略: 允许你在队列声明时自动将队列设置为镜像队列,从而实现消息冗余备份和高可用性。
  2. 队列过期策略: 允许你设置队列中的消息的过期时间,当消息过期时,RabbitMQ 会自动将其从队列中删除。
  3. 消息最大长度策略: 允许你限制队列中消息的最大长度,当队列中的消息数量达到设置的最大长度时,新的消息将被丢弃或处理为死信。
  4. 死信队列策略: 允许你将队列中无法被消费的消息自动发送到死信队列,以便进一步处理。
  5. 优先级队列策略: 允许你为消息设置优先级,并根据优先级将消息放入不同的队列中。

等等。

要设置策略,你可以使用 RabbitMQ Management 插件的管理界面,也可以使用命令行工具(如 rabbitmqctl)。通过设置策略,你可以实现自动化管理和配置,减少手动操作的需要,提高系统的可靠性和可维护性。

❓:策略如何设置

参数说明:

  1. Pattern(匹配模式):
  • 这是一个用于匹配交换器、队列和绑定的模式。可以使用通配符 *#
  • 例如,你可以使用 amq.* 匹配所有以 amq. 开头的交换器。
  1. Definition(定义):
  • 这是一个包含策略定义的 JSON 对象。具体的参数和值取决于你想要配置的策略类型。
  • 例如,如果要创建一个镜像队列策略,可以定义 ha-mode 和其他相关参数。
  1. ha-mode(镜像队列模式):
  • 用法:ha-mode = allha-mode = exactlyha-mode = nodes
  • 作用:定义队列是否为镜像队列,从而实现消息冗余备份和高可用性。
  • all:将队列设置为镜像队列,在所有节点上创建队列的镜像。
  • exactly:将队列设置为镜像队列,并指定要创建的镜像节点数量。
  • nodes:将队列设置为镜像队列,指定要在哪些节点上创建镜像。
  1. ha-params(镜像队列参数):
  • 用法:ha-params = ["node1", "node2"]
  • 作用:用于 ha-mode = nodes,指定创建队列镜像的节点列表。
  1. expires(消息过期时间):
  • 用法:expires = 3600000(毫秒)
  • 作用:定义队列中消息的过期时间,过期的消息将被自动删除。
  1. message-ttl(消息存活时间):
  • 用法:message-ttl = 60000(毫秒)
  • 作用:定义消息在队列中的存活时间,超过该时间的消息将被自动删除。
  1. max-length(最大消息数量):
  • 用法:max-length = 1000
  • 作用:限制队列中消息的最大数量,当队列中的消息数量达到指定值时,新的消息将被丢弃或处理为死信。
  1. dead-letter-exchange(死信交换器):
  • 用法:dead-letter-exchange = dlx_exchange
  • 作用:指定死信队列中的消息应该发送到的交换器。
  1. dead-letter-routing-key(死信路由键):
  • 用法:dead-letter-routing-key = dlx_routing_key
  • 作用:指定死信队列中的消息应该使用的路由键。
  1. max-length-bytes(最大消息字节数):
  • 用法:max-length-bytes = 102400
  • 作用:限制队列中消息的总字节数,当队列中消息的总字节数达到指定值时,新的消息将被丢弃或处理为死信。
  1. lazy-mode(延迟模式):
  • 用法:lazy-mode = onlazy-mode = off
  • 作用:启用或禁用延迟模式,用于将队列中的消息保存到磁盘以降低内存使用。
  1. queue-mode(队列模式):
  • 用法:queue-mode = lazyqueue-mode = default
  • 作用:定义队列的工作模式,lazy 表示延迟模式,default 表示默认模式。
  1. Priority(优先级):
  • 用于指定策略的优先级,当有多个策略匹配时,优先级较高的策略会覆盖较低的策略。
  • 优先级通常使用整数表示,值越小表示优先级越高。
  1. 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可以是任意的,第三个是配置文件

上面部分语句说明如下

  1. entrypoint: /bin/bash -c "rabbitmq-server rabbitmqctl wait /var/lib/rabbitmq/mnesia/rabbit@rabbitmq-node3.pid && rabbitmqctl join_cluster rabbit@rabbitmq-node1":等待并加入集群
  2. RABBITMQ_PLUGINS=--offline rabbitmq_delayed_message_exchange:指定要加载的插件,且加载预先下载好的
  3. 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是一样的

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
5天前
|
存储 监控 Linux
docker构建镜像详解!!!
本文回顾了Docker的基本命令和管理技巧,包括容器和镜像的增删改查操作,容器的生命周期管理,以及如何通过端口映射和数据卷实现容器与宿主机之间的网络通信和数据持久化。文章还详细介绍了如何使用Docker部署一个简单的Web应用,并通过数据卷映射实现配置文件和日志的管理。最后,文章总结了如何制作自定义镜像,包括Nginx、Python3和CentOS镜像,以及如何制作私有云盘镜像。
59 2
|
14天前
|
Kubernetes 负载均衡 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
本文介绍了Docker和Kubernetes在构建高效微服务架构中的应用,涵盖基本概念、在微服务架构中的作用及其实现方法。通过具体实例,如用户服务、商品服务和订单服务,展示了如何利用Docker和Kubernetes实现服务的打包、部署、扩展及管理,确保微服务架构的稳定性和可靠性。
57 7
|
13天前
|
Kubernetes 负载均衡 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
【10月更文挑战第22天】随着云计算和容器技术的快速发展,微服务架构逐渐成为现代企业级应用的首选架构。微服务架构将一个大型应用程序拆分为多个小型、独立的服务,每个服务负责完成一个特定的功能。这种架构具有灵活性、可扩展性和易于维护的特点。在构建微服务架构时,Docker和Kubernetes是两个不可或缺的工具,它们可以完美搭档,为微服务架构提供高效的支持。本文将从三个方面探讨Docker和Kubernetes在构建高效微服务架构中的应用:一是Docker和Kubernetes的基本概念;二是它们在微服务架构中的作用;三是通过实例讲解如何使用Docker和Kubernetes构建微服务架构。
50 6
|
12天前
|
负载均衡 应用服务中间件 nginx
基于Nginx和Consul构建自动发现的Docker服务架构——非常之详细
通过使用Nginx和Consul构建自动发现的Docker服务架构,可以显著提高服务的可用性、扩展性和管理效率。Consul实现了服务的自动注册与发现,而Nginx则通过动态配置实现了高效的反向代理与负载均衡。这种架构非常适合需要高可用性和弹性扩展的分布式系统。
18 4
|
13天前
|
负载均衡 应用服务中间件 nginx
基于Nginx和Consul构建自动发现的Docker服务架构——非常之详细
通过使用Nginx和Consul构建自动发现的Docker服务架构,可以显著提高服务的可用性、扩展性和管理效率。Consul实现了服务的自动注册与发现,而Nginx则通过动态配置实现了高效的反向代理与负载均衡。这种架构非常适合需要高可用性和弹性扩展的分布式系统。
28 3
|
18天前
|
jenkins 测试技术 持续交付
Docker最佳实践:构建高效的CI/CD流水线
【10月更文挑战第17天】在现代软件开发实践中,持续集成(Continuous Integration, CI)和持续部署(Continuous Deployment, CD)已成为提高开发效率和软件质量的重要手段。Docker作为一种容器技术,为构建一致且隔离的开发环境提供了强有力的支撑。本文将探讨如何利用Docker来优化CI/CD流程,包括构建环境的标准化、镜像管理以及与CI/CD工具(如Jenkins、GitLab CI)的集成。
36 5
|
17天前
|
JavaScript Docker Python
下个时代的开发工具-Nix:声明式的运行环境构建器、简单场景下的docker替身
Nix 是一个独特的包管理工具和构建系统,采用声明式方法管理软件包和运行环境。它通过精确控制依赖关系和环境配置,确保软件的可重复性、隔离性和可追溯性。Nix 支持多语言开发环境,提供声明式配置、环境隔离、回滚与版本控制等核心功能,适用于复杂开发场景,有效解决依赖冲突和环境不一致问题。
|
17天前
|
运维 资源调度 调度
容器微服务运维
【10月更文挑战第16天】业务容器化后,运维需采用面向容器的新型平台,主要由镜像仓库、资源调度、容器调度、调度策略和服务编排组成。镜像仓库负责存储与分发容器镜像,支持权限控制、镜像同步和高可用性设计;资源调度解决不同环境下的机器部署问题;容器调度实现容器在主机上的合理分配;调度策略优化容器主机选择;服务编排则处理服务间的依赖关系和服务发现,支持自动扩缩容以适应业务需求变化。
|
Linux Docker Windows
Docker概述:什么Docker如此特别,它是如何构建的
本文讲的是Docker概述:什么Docker如此特别,它是如何构建的,【编者的话】在上一系列介绍中,我们大体地介绍了CoreOS。在这个系列中我想介绍一下Docker。本文我们看一下为什么Docker如此特别,它是如何构建的。我们会从基本开始介绍,所以读者不必担心自己是刚接触Docker的。
1373 0
|
3天前
|
关系型数据库 MySQL API