RabbitMQ集群

一、为什么需要集群?

前面章节我们介绍了如何安装及运行 RabbitMQ 服务,不过这些是单机版的 RabbitMQ 服务。单机版的 RabbitMQ 服务用来学习完全没有问题,但是无法满足应用程序复杂的生产环境真实的要求。

如果 RabbitMQ 服务器遇到内存崩溃、机器掉电或者主板故障等情况,该怎么办?

如果单台 RabbitMQ 服务器可以满足每秒 1000 条消息的吞吐量,如果应用需要 RabbitMQ 服务满足每秒 10 万条消息的吞吐量呢?

最简单办法就是购买昂贵的服务器来增强单机 RabbitMQ 服务的性能,毕竟单机性能是有限的,应用程序性能需求是无限的。因此,搭建一个 RabbitMQ 集群才是解决实际问题的关键点。

RabbitMQ 集群允许消费者和生产者在 RabbitMQ 单个节点崩惯的情况下继续运行,它可以通过添加更多的节点来线性地扩展消息通信的吞吐量。当失去一个 RabbitMQ 节点时,客户端能够重新连接到集群中的任何其他节点并继续生产或者消费。

二、RabbitMQ集群的说明

RabbitMQ集群的两种方式:

  • 普通集群模式:rabbitmq集群与其他集群有些不同,rabbitmq集群同步的指是复制队列,元数据信息的同步,即同步的是数据存储信息;消息的存放只会存储在创建该消息队列的那个节点上。并非在节点上都存储一个完整的数据。在通过非数据所在节点获取数据时,通过元数据信息,路由转发到存储数据节点上,从而得到数据 。
  • 镜像集群模式:与普通集群模式区别 主要是消息实体会主动在镜像节点间同步数据,而不是只存储数据元信息。 故普通集群模式 但凡数据节点挂了,容易造成数据丢失但镜像集群模式可以保证集群只要不全部挂掉,数据就不会丢失,当相对于性能来说,镜像集群模式会比普通集群模式多出消耗数据的传输。故取决于业务场景进行取舍。

三、普通集群模式

普通模式架构图如下:

3.1.拉取rabbitmq镜像

执行如下命令:

docker pull rabbitmq:3.12-management

3.2.创建映射数据卷目录,启动rabbitmq容器

3.2.1.执行如下命令创建文件夹:

进入后创建即可

# 创建目录
[root@bogon ~]# mkdir -p /home/soft/rabbitmqcluster
# 进入路径
[root@bogon ~]# cd /home/soft/rabbitmqcluster
# 创建三个子目录,作为后续容器的映射路径
[root@bogon rabbitmqcluster]# mkdir rabbitmq01 rabbitmq02 rabbitmq03
# 查看确保创建成功
[root@bogon rabbitmqcluster]# ls
rabbitmq01  rabbitmq02  rabbitmq03
[root@bogon rabbitmqcluster]#

3.2.2.创建容器

执行如下命令创建三个RabbitMQ容器,作为集群使用:

docker run -d --hostname rabbitmq01 --name rabbitmqCluster01 -v /home/soft/rabbitmqcluster/rabbitmq01:/var/lib/rabbitmq -p 15672:15672 -p 5672:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' rabbitmq:3.12-management
docker run -d --hostname rabbitmq02 --name rabbitmqCluster02 -v /home/soft/rabbitmqcluster/rabbitmq02:/var/lib/rabbitmq -p 15673:15672 -p 5673:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie'  --link rabbitmqCluster01:rabbitmq01 rabbitmq:3.12-management
docker run -d --hostname rabbitmq03 --name rabbitmqCluster03 -v /home/soft/rabbitmqcluster/rabbitmq03:/var/lib/rabbitmq -p 15674:15672 -p 5674:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie'  --link rabbitmqCluster01:rabbitmq01 --link rabbitmqCluster02:rabbitmq02  rabbitmq:3.12-management

参数的作用和含义:

  • -d:以后台(detached)模式运行容器。

  • --hostname rabbitmq03:设置容器的主机名为rabbitmq03

  • --name rabbitmqCluster03:为容器指定一个名称为rabbitmqCluster03

  • -v /home/soft/rabbitmqcluster/rabbitmq03:/var/lib/rabbitmq:将本地文件系统中的/home/soft/rabbitmqcluster/rabbitmq03目录挂载到容器内的/var/lib/rabbitmq目录,实现数据持久化。

  • -p 15674:15672:将容器内的15672端口映射到宿主机的15674端口,用于访问 RabbitMQ 管理界面。

  • -p 5674:5672:将容器内的5672端口映射到宿主机的5674端口,用于 RabbitMQ 客户端连接。

  • -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie':设置环境变量RABBITMQ_ERLANG_COOKIE的值为rabbitmqCookie,用于指定 RabbitMQ 集群节点之间的通信密钥。

  • --link rabbitmqCluster01:rabbitmq01:将容器rabbitmqCluster01的网络连接信息注入到当前容器中,使得容器内可以通过rabbitmq01主机名访问rabbitmqCluster01容器。

  • --link rabbitmqCluster02:rabbitmq02:将容器rabbitmqCluster02的网络连接信息注入到当前容器中,使得容器内可以通过rabbitmq02主机名访问rabbitmqCluster02容器。

  • rabbitmq:3.12-management:指定使用的 RabbitMQ 镜像及版本,3.12-management表示带有管理界面的 RabbitMQ 版本。

综上所述,该命令将在后台运行一个名为rabbitmqCluster03的容器,使用指定的镜像和版本创建 RabbitMQ 集群节点。容器内的 RabbitMQ 实例将通过指定的端口映射到宿主机上,同时通过链接其他两个 RabbitMQ 容器,实现集群节点之间的通信。挂载本地目录用于持久化存储 RabbitMQ 数据。

注意:由于Erlang节点间通过认证Erlang cookie的方式来允许互相通信,所以RABBITMQ_ERLANG_COOKIE三个容器必须设置为相同的。启动完成之后,使用docker ps命令查看运行情况,确保RabbitMQ都已经启动。

启动容器成功后,读者可以访问:

http://192.168.42.132:15672/#/
http://192.168.42.132:15673/#/
http://192.168.42.132:15674/#/

查看是否正常启动成功。账号/密码:guest / guest。

3.3.容器节点加入集群

3.3.1.容器一操作

进入第一个rabbitmq节点容器:

docker exec -it rabbitmqCluster01 bash

进入容器后,操作rabbitmq,执行如下命令:

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit

3.3.2.容器二操作

进入第一个rabbitmq节点容器:

docker exec -it rabbitmqCluster02 bash

进入容器后,操作rabbitmq,执行如下命令:

# 停止 RabbitMQ 应用程序,即停止 RabbitMQ 服务。
rabbitmqctl stop_app
# 重置 RabbitMQ 节点,包括清除所有队列、交换机、绑定等数据,恢复到初始状态。
rabbitmqctl reset
# 将当前节点加入到名为rabbitmq01的 RabbitMQ 集群中,并以内存节点(RAM Node)的方式加入。这意味着当前节点将作为一个只读节点加入集群,不参与数据的持久化和复制。
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
# 启动 RabbitMQ 应用程序,即启动 RabbitMQ 服务。
rabbitmqctl start_app
# 退出当前命令行终端。
exit

3.3.2.容器三操作

进入第一个rabbitmq节点容器:

docker exec -it rabbitmqCluster03 bash

进入容器后,操作rabbitmq,执行如下命令:

# 停止 RabbitMQ 应用程序,即停止 RabbitMQ 服务。
rabbitmqctl stop_app
# 重置 RabbitMQ 节点,包括清除所有队列、交换机、绑定等数据,恢复到初始状态。
rabbitmqctl reset
# 将当前节点加入到名为rabbitmq01的 RabbitMQ 集群中,并以内存节点(RAM Node)的方式加入。这意味着当前节点将作为一个只读节点加入集群,不参与数据的持久化和复制。
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
# 启动 RabbitMQ 应用程序,即启动 RabbitMQ 服务。
rabbitmqctl start_app
# 退出当前命令行终端。
exit

执行上述操作,这时候分别登陆三个RabbitMQ的overview面板中的Nodes信息,可查看到节点信息,三个容器构成了集群:

3.4.负载均衡设置

当集群集群搭建完毕之后,还要设置负载均,以防止出现对单一节点造成高负载的情况。本次测试用例 采用nginx中间件。

3.4.1.创建Nginx配置文件

在本机上存放着一个nginx配置文件:/home/soft/nginx/nginx_rabbitmq.conf,内容如下:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    
    proxy_redirect          off;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size    10m;
    client_body_buffer_size   128k;
    proxy_connect_timeout   5s;
    proxy_send_timeout      5s;
    proxy_read_timeout      5s;
    proxy_buffer_size        4k;
    proxy_buffers           4 32k;
    proxy_busy_buffers_size  64k;
    proxy_temp_file_write_size 64k;
    #rabbitmq管理界面
    upstream rabbitManage {
        server 192.168.42.132:15672;
        server 192.168.42.132:15673;
        server 192.168.42.132:15674;
    }
    server {
        listen       15675;
        server_name  192.168.42.132; 
        location / {  
            proxy_pass   http://rabbitManage;
            index  index.html index.htm;  
        }  

    }
}
# rabbitmq通信
stream{
    upstream rabbitTcp{
        server 192.168.42.132:5672;
        server 192.168.42.132:5673;
        server 192.168.42.132:5674;
    }

    server {
        listen 5675;
        proxy_pass rabbitTcp;
    }
}

注意:上面配置了rabbitmq管理界面和通信的反向代理

3.4.2.创建启动nginx容器

执行如下命令创建Nginx容器:

docker run -it -d --name nginxRabbitmq -v /home/soft/nginx/nginx_rabbitmq.conf:/etc/nginx/nginx.conf --privileged --net=host nginx

参数的含义:

  • -it:以交互模式运行容器,并分配一个伪终端(pseudo-TTY)。

  • -d:以后台(detached)模式运行容器。

  • --name nginxRabbitmq:为容器指定一个名称为nginxRabbitmq

  • -v /home/soft/nginx/nginx_rabbitmq.conf:/etc/nginx/nginx.conf:将本地文件系统中的/home/soft/nginx/nginx_rabbitmq.conf文件挂载到容器内的/etc/nginx/nginx.conf文件,用于配置 Nginx。

  • --privileged:以特权模式运行容器,拥有访问主机设备的权限。

  • --net=host:使用主机网络模式,容器与主机共享网络命名空间,可以直接访问主机的网络接口。

  • nginx:指定使用的镜像为 Nginx

接着可以通过 http://192.168.42.132:15675 进行管理 以及通过 5675 端口 进行rabbitmq通信。账户密码依然是guest,如下图:

这里直接访问有时候会出现无法访问,可以通过如下方法解决:

  • 重启所有的容器:
docker restart 44fa5e8b3e21 b74144e658a3  31aede811aea cf3aca85690b
  • 然后启动防火墙,然后关闭 :
# 开启
service firewalld start
# 关闭
service firewalld stop

四、镜像集群模式

4.1.镜像集群模式是什么?

rabbitmq镜像集群依赖于普通集群,所以需要先搭建rabbitmq普通集群

镜像集群模式其实就是把需要的队列做成镜像队列,然后将镜像队列放在多个节点当中,这种镜像集群模式解决了普通集群模式没有做到的高可用性的缺点,镜像集群模式属于Rabbit MQ的高可用性的集群部署方案。

普通队列进程及其内容仅仅维持在单个节点之上,所以一个节点的失效表现为其对应的队列不可用。

引入镜像队列(Mirror Queue)的机制,可以将队列镜像到集群中的其他Broker节点之上,如果集群中的一个节点失效了,队列能够自动切换到镜像中的另一个节点上以保证服务的可用性。

针对每个队列的(以下简称镜像队列)都包含一个主节点(master)和若干个从节点(slave),架构如下:

4.2.拉取rabbitmq镜像

执行如下命令:

docker pull rabbitmq:3.12-management

4.2.创建映射数据卷目录,启动rabbitmq容器

4.2.1.执行如下命令创建文件夹:

进入后创建即可

# 创建目录
[root@bogon ~]# mkdir -p /home/soft/rabbitmqcluster
# 进入路径
[root@bogon ~]# cd /home/soft/rabbitmqcluster
# 创建三个子目录,作为后续容器的映射路径
[root@bogon rabbitmqcluster]# mkdir rabbitmq01 rabbitmq02 rabbitmq03
# 查看确保创建成功
[root@bogon rabbitmqcluster]# ls
rabbitmq01  rabbitmq02  rabbitmq03
[root@bogon rabbitmqcluster]#

4.2.2.创建容器

执行如下命令创建三个RabbitMQ容器,作为集群使用:

docker run -d --hostname rabbitmq01 --name rabbitmqCluster01 -v /home/soft/rabbitmqcluster/rabbitmq01:/var/lib/rabbitmq -p 15672:15672 -p 5672:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' rabbitmq:3.12-management
docker run -d --hostname rabbitmq02 --name rabbitmqCluster02 -v /home/soft/rabbitmqcluster/rabbitmq02:/var/lib/rabbitmq -p 15673:15672 -p 5673:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie'  --link rabbitmqCluster01:rabbitmq01 rabbitmq:3.12-management
docker run -d --hostname rabbitmq03 --name rabbitmqCluster03 -v /home/soft/rabbitmqcluster/rabbitmq03:/var/lib/rabbitmq -p 15674:15672 -p 5674:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie'  --link rabbitmqCluster01:rabbitmq01 --link rabbitmqCluster02:rabbitmq02  rabbitmq:3.12-management

参数的作用和含义:

  • -d:以后台(detached)模式运行容器。

  • --hostname rabbitmq03:设置容器的主机名为rabbitmq03

  • --name rabbitmqCluster03:为容器指定一个名称为rabbitmqCluster03

  • -v /home/soft/rabbitmqcluster/rabbitmq03:/var/lib/rabbitmq:将本地文件系统中的/home/soft/rabbitmqcluster/rabbitmq03目录挂载到容器内的/var/lib/rabbitmq目录,实现数据持久化。

  • -p 15674:15672:将容器内的15672端口映射到宿主机的15674端口,用于访问 RabbitMQ 管理界面。

  • -p 5674:5672:将容器内的5672端口映射到宿主机的5674端口,用于 RabbitMQ 客户端连接。

  • -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie':设置环境变量RABBITMQ_ERLANG_COOKIE的值为rabbitmqCookie,用于指定 RabbitMQ 集群节点之间的通信密钥。

  • --link rabbitmqCluster01:rabbitmq01:将容器rabbitmqCluster01的网络连接信息注入到当前容器中,使得容器内可以通过rabbitmq01主机名访问rabbitmqCluster01容器。

  • --link rabbitmqCluster02:rabbitmq02:将容器rabbitmqCluster02的网络连接信息注入到当前容器中,使得容器内可以通过rabbitmq02主机名访问rabbitmqCluster02容器。

  • rabbitmq:3.12-management:指定使用的 RabbitMQ 镜像及版本,3.12-management表示带有管理界面的 RabbitMQ 版本。

综上所述,该命令将在后台运行一个名为rabbitmqCluster03的容器,使用指定的镜像和版本创建 RabbitMQ 集群节点。容器内的 RabbitMQ 实例将通过指定的端口映射到宿主机上,同时通过链接其他两个 RabbitMQ 容器,实现集群节点之间的通信。挂载本地目录用于持久化存储 RabbitMQ 数据。

注意:由于Erlang节点间通过认证Erlang cookie的方式来允许互相通信,所以RABBITMQ_ERLANG_COOKIE三个容器必须设置为相同的。启动完成之后,使用docker ps命令查看运行情况,确保RabbitMQ都已经启动。

启动容器成功后,读者可以访问:

http://192.168.42.147:15672/#/
http://192.168.42.147:15673/#/
http://192.168.42.147:15674/#/

查看是否正常启动成功。账号/密码:guest / guest。

4.3.容器节点加入集群

4.3.1.容器一操作

进入第一个rabbitmq节点容器:

docker exec -it rabbitmqCluster01 bash

进入容器后,操作rabbitmq,执行如下命令:

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit

4.3.2.容器二操作

进入第一个rabbitmq节点容器:

docker exec -it rabbitmqCluster02 bash

进入容器后,操作rabbitmq,执行如下命令:

# 停止 RabbitMQ 应用程序,即停止 RabbitMQ 服务。
rabbitmqctl stop_app
# 重置 RabbitMQ 节点,包括清除所有队列、交换机、绑定等数据,恢复到初始状态。
rabbitmqctl reset
# 将当前节点加入到名为rabbitmq01的 RabbitMQ 集群中,并以内存节点(RAM Node)的方式加入。这意味着当前节点将作为一个只读节点加入集群,不参与数据的持久化和复制。
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
# 启动 RabbitMQ 应用程序,即启动 RabbitMQ 服务。
rabbitmqctl start_app
# 退出当前命令行终端。
exit

4.3.3.容器三操作

进入第一个rabbitmq节点容器:

docker exec -it rabbitmqCluster03 bash

进入容器后,操作rabbitmq,执行如下命令:

# 停止 RabbitMQ 应用程序,即停止 RabbitMQ 服务。
rabbitmqctl stop_app
# 重置 RabbitMQ 节点,包括清除所有队列、交换机、绑定等数据,恢复到初始状态。
rabbitmqctl reset
# 将当前节点加入到名为rabbitmq01的 RabbitMQ 集群中,并以内存节点(RAM Node)的方式加入。这意味着当前节点将作为一个只读节点加入集群,不参与数据的持久化和复制。
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
# 启动 RabbitMQ 应用程序,即启动 RabbitMQ 服务。
rabbitmqctl start_app
# 退出当前命令行终端。
exit

执行上述操作,这时候分别登陆三个RabbitMQ的overview面板中的Nodes信息,可查看到节点信息,三个容器构成了集群:

4.3.4.HA mode 同步方式

4.3.4.1. 参数说明

One of all (mirror to all nodes in the cluster), exactly (mirror to a set number of nodes) or nodes (mirror to an explicit list of nodes). If you choose one of the latter two, you must also set ha-params。HA mode的值共有三个

  • all:镜像同步到集群队列的所有节点
  • exactly:按个数同步到集群中的一个或多个节点
  • nodes:具体的节点名称

如果选择后面两个选项的的值,还需要设置ha-params参数。RabbitMQ关于策略设置有两种方式:

  • 基于图形化界面设置
  • 通过命令终端设置

下面在图形化界面进行策略设置如下:

"Add / update an operator policy" 是指添加或更新操作员策略。操作员策略用于定义操作员用户在 RabbitMQ 上执行的操作的权限和限制。以下是各个参数的含义:

  • pattern:用于匹配操作员用户的用户名的正则表达式模式。只有匹配该模式的操作员用户才会受到该策略的影响。
  • definition:定义了操作员策略的具体配置。它是一个 JSON 格式的字符串,包含了一系列的配置项和值。
  • apply-to:指定策略应用的对象。可以选择的选项有:
    1. Queues(队列):选择此选项将策略应用于所有类型的队列,包括经典队列(Classic Queues)、镜像队列(Mirrored Queues)、延迟队列(Delayed Queues)等。这是最常见的选项,适用于大多数情况。
    2. Classic Queues(经典队列):选择此选项将策略仅应用于经典队列。经典队列是 RabbitMQ 最常见的队列类型,它们在单个节点上存储消息。
    3. Quorum Queues(Quorum 队列):选择此选项将策略仅应用于 Quorum 队列。Quorum 队列是 RabbitMQ 从版本3.8开始引入的一种队列类型,它们使用 Raft 一致性协议在多个节点之间复制和存储消息,提供更高的可靠性和性能。
    4. Streams(流队列):选择此选项将策略仅应用于流队列。流队列是 RabbitMQ 从版本3.9开始引入的一种队列类型,它们基于 AMQP 1.0 协议,支持持久化、分区和流式处理等特性,适用于高吞吐量和大规模数据流的场景。
  • priority:策略的优先级。当多个策略同时匹配时,优先级较高的策略将覆盖优先级较低的策略。

通过添加或更新操作员策略,可以对操作员用户的权限进行精细的控制和限制。例如,可以限制操作员用户只能访问特定的交换器或队列,或者限制他们只能执行特定的操作,如发布消息、创建队列等。这样可以提高系统的安全性和管理灵活性。

4.3.4.2.作用说明

所有队列设置为镜像队列,即队列会被复制到集群各个节点,各个集群节点交换机、队列、队列内容都保持一致。

4.3.4.3.案例说明(在命令行终端设置)

最后,实现镜像模式集群。进入rabbitmqCluster01容器中

docker exec -it rabbitmqCluster01 bash

执行如下命令:

rabbitmqctl set_policy -p / ha-all "^" '{"ha-mode":"all"}'

说明:

  • rabbitmqctl set_policy 是 RabbitMQ 的命令行工具,用于设置策略(policy)。-p 参数用于指定虚拟主机(vhost),ha-all 是策略的名称。
  • {"ha-mode":"all"} 是一个 JSON 格式的字符串,表示策略的配置。在这个例子中,ha-mode 是配置项,它的值是 "all",为 all 即复制到所有节点,包含新增节点,策略正则表达式为 “^” 表示所有匹配所有队列名称。这个配置的含义是将 RabbitMQ 中的所有队列都设置为高可用模式。
  • 高可用模式(Highly Available,简称 HA)是 RabbitMQ 提供的一种机制,用于确保消息队列的可靠性和冗余性。当队列被设置为高可用模式时,RabbitMQ 会自动在多个节点之间进行数据复制,以保证即使某个节点发生故障,消息仍然可以被处理。
  • 通过设置策略,将所有队列都设置为高可用模式,可以提高整个 RabbitMQ 系统的可用性和容错性。这样即使某个节点发生故障,其他节点上的队列仍然可以继续工作,确保消息的可靠传递。

例如:

rabbitmqctl set_policy -p / ha-all "^message" '{"ha-mode":"all"}'

注意:“^message” 这个规则要根据自己修改,这个是指同步“message”开头的队列名称,之前的案例配置时使用的应用于所有队列,所以表达式为“^”

当设置后,在任意一个rabbitMQ中,创建一个交换机和在队列,其他的rabbitMQ中自动同步,如下:

  • 交换机

  • 队列

4.4.负载均衡设置

集群搭建之后还要设置负载均,为了防止出现对单一节点造成高负载的情况。下面采用nginx中间件。

4.4.1.本机上存放着两个nginx配置文件:

下面两个nginx配置文件都是用于创建配置nginx容器的,都是代理上一个章节的集群,区别是两个nginx代码后通过访问的地址不同。这个也是下面配置文件的区别:

  • nginx1:192.168.42.147:15675 服务端口5675
  • nginx2:192.168.42.147:15676 服务端口5676

在 /home/software/nginx/  创建:nginx_rabbitmq_1.conf,内容如下:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    
    proxy_redirect          off;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size    10m;
    client_body_buffer_size   128k;
    proxy_connect_timeout   5s;
    proxy_send_timeout      5s;
    proxy_read_timeout      5s;
    proxy_buffer_size        4k;
    proxy_buffers           4 32k;
    proxy_busy_buffers_size  64k;
    proxy_temp_file_write_size 64k;
    #rabbitmq管理界面
    upstream rabbitManage {
        server 192.168.42.147:15672;
        server 192.168.42.147:15673;
        server 192.168.42.147:15674;
    }
    server {
        listen       15675;
        server_name  192.168.42.147; 
        location / {  
            proxy_pass   http://rabbitManage;
            index  index.html index.htm;  
        }  

    }
}
# rabbitmq通信
stream{
    upstream rabbitTcp{
        server 192.168.42.147:5672;
        server 192.168.42.147:5673;
        server 192.168.42.147:5674;
    }

    server {
        listen 5675;
        proxy_pass rabbitTcp;
    }
}

在 /home/software/nginx/  创建:nginx_rabbitmq_2.conf,内容如下:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    
    proxy_redirect          off;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size    10m;
    client_body_buffer_size   128k;
    proxy_connect_timeout   5s;
    proxy_send_timeout      5s;
    proxy_read_timeout      5s;
    proxy_buffer_size        4k;
    proxy_buffers           4 32k;
    proxy_busy_buffers_size  64k;
    proxy_temp_file_write_size 64k;
    #rabbitmq管理界面
    upstream rabbitManage {
        server 192.168.42.147:15672;
        server 192.168.42.147:15673;
        server 192.168.42.147:15674;
    }
    server {
        listen       15676;
        server_name  192.168.42.147; 
        location / {  
            proxy_pass   http://rabbitManage;
            index  index.html index.htm;  
        }  

    }
}
# rabbitmq通信
stream{
    upstream rabbitTcp{
        server 192.168.42.147:5672;
        server 192.168.42.147:5673;
        server 192.168.42.147:5674;
    }

    server {
        listen 5676;
        proxy_pass rabbitTcp;
    }
}

注意:上面配置了rabbitmq管理界面和通信的反向代理

4.4.2.创建两个nginx容器

执行如下命令:

docker run -it -d --name nginxRabbitmq1 -v /home/software/nginx/nginx_rabbitmq_1.conf:/etc/nginx/nginx.conf --privileged --net=host nginx
docker run -it -d --name nginxRabbitmq2 -v /home/software/nginx/nginx_rabbitmq_2.conf:/etc/nginx/nginx.conf --privileged --net=host nginx

创建成功后,可以通过访问 http://192.168.42.147:15675 以及 http://192.168.42.147:15676 进行测试。是否搭建成功。这里直接访问有时候会出现无法访问,可以通过如下方法解决:

  • 重启所有的容器:
docker restart 847d99e500e3 55b3713e775e ff8af3410072 e96851a2c296 d3d9450260dd
  • 然后启动防火墙,然后关闭 :
# 开启
service firewalld start
# 关闭
service firewalld stop

4.5.安装keepalived实现HA

4.5.1.keepalived是什么,有什么作用?

Keepalived 是一个基于 VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)的开源软件,用于实现高可用性和故障转移。它主要用于在多个服务器之间创建一个虚拟 IP 地址(VIP),并确保该 VIP 在服务器之间的故障转移。

Keepalived 的主要作用如下:

  1. 高可用性:通过使用 VRRP 协议,Keepalived 可以将多个服务器组成一个高可用性集群。在集群中,只有一个服务器拥有 VIP,该服务器被称为 Master 节点,其他服务器处于 Backup 状态。如果 Master 节点发生故障,Backup 节点中的一个将接管 VIP,确保服务的持续可用性。

  2. 故障转移:当 Master 节点发生故障或不可用时,Keepalived 能够自动将 VIP 转移到 Backup 节点,实现快速的故障转移。这样可以避免单点故障,提高系统的可靠性和稳定性。

  3. 健康检查:Keepalived 可以定期对服务器进行健康检查,以确保服务器的可用性。如果服务器无法正常响应健康检查,Keepalived 将自动将其标记为不可用,并将 VIP 转移到其他可用的服务器上。

  4. 负载均衡:除了故障转移和高可用性,Keepalived 还可以与负载均衡器结合使用,将流量分发到多个服务器上,实现负载均衡和提高系统的性能。

Keepalived 是一个用于实现高可用性和故障转移的软件,通过使用 VRRP 协议和虚拟 IP 地址,确保在服务器故障或不可用时,服务能够快速切换到其他可用的服务器上,保证系统的可用性和稳定性。

4.5.2.在两个nginx容器分别安装keepalived,并编写keepalived配置文件以及启动keepalived

4.5.2.1.进入nginxRabbitmq1容器中,执行如下命令:

安装keepalived,如下:

apt-get  -y update
apt-get -y  install vim
apt-get -y install keepalived

安装完成后,编写keekpalived.conf:

vim /etc/keepalived/keepalived.conf

内容如下:

注意interface后面的一定写自己的服务器网卡名字,我这里的网卡名字是ens33,虚拟ip和端口映射Nginx1的ip和端口

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    
    # 虚拟ip,从系统选择一个IP
    virtual_ipaddress {
        192.168.42.148
    }
}
# 设置虚拟ip的15678和nginx1进行绑定
virtual_server 192.168.42.148 15678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    # nginx1的图形化界面
    real_server 192.168.42.147 15675 {
        weight 1
    }
}
# 设置虚拟ip的5678和nginx1的服务端口5675进行绑定
virtual_server 192.168.42.148 5678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    # nginx1的连接端口
    real_server 192.168.42.147 5675 {
        weight 1
    }
}

保存完配置,启动keepalived

service keepalived start

注:interface 表示绑定的网络接口,请用ip addr 查看本机的网卡进行替换 ,virtual_router_id 表示keepalived家族标识信息,全局唯一,节点间保持相同

上面的配置文件interface后面一定要写网卡名称,切记切记!!!

4.5.2.2.进入nginxRabbitmq2容器中,执行如下命令:

apt-get -y update
apt-get -y install vim
apt-get -y install keepalived

安装完成后,编写keekpalived.conf,

vim /etc/keepalived/keepalived.conf

内容如下:注意interface 写网卡名称,虚拟ip和端口映射Nginx2的ip和端口

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.42.148
    }
}
virtual_server 192.168.42.148 15678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 192.168.42.147 15676 {
        weight 1
    }
}
virtual_server 192.168.42.148 5678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 192.168.42.147 5676 {
        weight 1
    }
}

保存完配置,启动keepalived

service keepalived start

4.6.主机上安装keepaplived进行转发

执行如下命令:

yum -y install keepalived

安装完成后,编写配置文件keepalived.conf,注意interface 写网卡名称, 是下的ip192.168.42.148配置的之前上面配置的Nginx中keepalived的虚拟ip。一定要用虚拟IP,不能用真实的ip地址:

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface eno16777736
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.42.149
    }
}
# 主机虚拟ip跟nginx中虚拟ip图形化界面端口绑定
virtual_server 192.168.42.149 15678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 192.168.42.148 15675 {
        weight 1
    }
    real_server 192.168.42.148 15676{
        weight 1
    }

}
# 主机虚拟ip跟nginx中虚拟ip服务端口绑定
virtual_server 192.168.42.149 5678 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 192.168.42.148 5675 {
        weight 1
    }
    real_server 192.168.42.148 5676 {
        weight 1
    }
}

保存完配置后,启动keepalived

service keepalived start

可以通过 http://192.168.42.149:15678 进行访问 以及通过 5678 端口 进行rabbitmq通信。

可以测试停止nginxRabbitmq1或者nginxRabbitmq2进行测试,依然能够正常访问

4.7.补充

keepalived配置文件部分说明

vrrp_instance VI_1 {              --- vrrp协议相关配置(vip地址设置)
    state MASTER                  --- keepalived角色描述(状态)信息,可以配置参数(MASTER BACKUP)
    interface eth0                --- 表示将生成虚IP地址,设置在指定的网卡上(一般为外网卡)替换成自己的切记!!!
    virtual_router_id 51          --- 表示keepalived家族标识信息
    priority 100                  --- keepalived服务竞选主备服务器优先级设置(越大越优先)
    advert_int 1                  --- 主服务组播包发送间隔时间       
    authentication {              --- 主备主机之间通讯认证机制,
        auth_type PASS            --- 采用明文认证机制
        auth_pass 123456            --- 编写明文密码(用于主备认证)
    }

    virtual_ipaddress {           --- 设置虚拟IP地址信息
       192.168.42.149
    }
   virtual_server 192.168.42.149 15678 {  --- 设置虚拟IP地址 端口转发
      delay_loop 3                    ---- service polling的delay时间,即服务轮询的时间间隔
      lb_algo rr                     --- LVS调度算法 
      lb_kind NAT                    --- LVS集群模式  
      persistence_timeout 50          --- 会话保持时间(秒为单位),即以用户在120秒内被分配到同一个后端realserver
      protocol TCP                    --- 健康检查用的是TCP还是UDP
      real_server 192.168.42.148 15676 {
           weight 1                   --- 给每台的权重,0表示失效(不知给他转发请求知道他恢复正常),默认是1
   
     }
  }
}

RabbitMQ常见操作说明

#启动rabbitmq
rabbitmqctl start_app

#停止rabbitmq
rabbitmqctl stop_app

#rabbitmq 查看所有队列信息
rabbitmqctl list_queues

#还原 rabbitmq 清除所有队列
rabbitmqctl reset

#rabbitmq 查看用户
rabbitmqctl list_users

#rabbitmq添加用户
rabbitmqctl add_user root root

#rabbitmq设置权限
rabbitmqctl set_permissions -p / root ".*" ".*" ".*"

#rabbitmq查看集群状态信息
rabbitmqctl cluster_status

#移除某个集群节点:一般情况当节点故障时,在正常的节点中,移除该故障节点
rabbitmqctl  -n rabbit@rabbitmq01 forget_cluster_node rabbit@rabbitmq03

#如果遇到nginx 502问题请关闭防火墙。
systemctl stop firewalld.service
posted @ 2023-09-21 18:05  酒剑仙*  阅读(139)  评论(0)    收藏  举报