rabbitmq+nginx负载服务部署文档

前言

复制代码
rabbitmq普通集群部署后,存在服务单点承压的情况,故,需要通过前端负载解决单点承压的问题;将采用nginx作为负载器,对流量进行负载分发到各个集群节点,解决服务单点负载的问题

环境

虚拟机4台,如下列表

主机名 主机ip 用途 备注
nginx-lsb 10.0.3.132 负载器
rabbitmq01 10.0.3.133 rabbitmq-node1
rabbitmq02 10.0.3.134 rabbitmq-node2
rabbitmq03 10.0.3.135 rabbitmq-node3

同一个网络中

资源

名称 版本 类型 备注
centos 7.9.2009 操作系统
docker 26.1.4 软件 rpm部署
bitnami/rabbitmq latest 容器镜像 容器id:80583c0e1b06
nginx 1.27.0 容器镜像 容器id:e0c9858e10ed
pivotalrabbitmq/perf-test latest 容器镜像 容器id:3804df61f5ba

部署

系统环境准备(四个主机均要执行)

关闭防火墙

shell 复制代码
  systemctl stop firewalld
  systemctl disable firewalld

关闭selinux

shell 复制代码
  sed -i 's~SELINUX=enforcing~SELINUX=disabled~' /etc/selinux/config
  setenforce 0

新增一个数据目录(最好和系统盘分离)

shell 复制代码
  mkdir /data/docker

docker服务准备(四个主机)

shell 复制代码
  rm -rf /etc/yum.repos.d/*
  curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
  yum -y remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
  yum install -y yum-utils device-mapper-persistent-data lvm2
  yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  yum install -y docker-ce docker-ce-cli containerd.io
  mkdir /etc/docker/
  cat >> /etc/docker/daemon.json << EOF
  {
    "data-root": "/data/docker",
    "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn","http://hub-mirror.c.163.com"]
  }
  EOF
  systemctl restart docker 
  systemctl enable docker 
  wget https://github.com/docker/compose/releases/download/v2.28.0/docker-compose-linux-x86_64
  chmod 755 docker-compose-linux-x86_64
  \cp -fp ddocker-compose-linux-x86_64 /usr/bin/docker-compose

镜像准备

shell 复制代码
  #在负载均衡(10.0.3.132)的虚机上执行
  docker pull nginx:1.27.0
  docker pull pivotalrabbitmq/perf-test
  #在rabbitmq的三个节点上执行
  docker pull bitnami/rabbitmq
  docker pull pivotalrabbitmq/perf-test

服务启动文件准备

nginx负载均衡的服务管理文件

shell 复制代码
mkdir -p /usr/yunji/nginx_4_lsb/conf.d
cat > /usr/yunji/nginx_4_lsb/docker-compose.yml << EOF
services:
  web:
    image: nginx:1.27.0
    container_name: nginx-web
    ports:
      - "5672:5672"
    volumes:
      - "$PWD/conf.d:/etc/nginx/conf.d"
      - "$PWD/nginx.conf:/etc/nginx/nginx.conf:ro"
    restart: no
EOF
cat > /usr/yunji/nginx_4_lsb/nginx.conf << EOF
user  root;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
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;
#
#    include /etc/nginx/conf.d/*.conf;
#}

stream {
    log_format proxy '$remote_addr [$time_local] '
                 '$protocol $status $bytes_sent $bytes_received '
                 '$session_time "$upstream_addr" '
                 '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
    access_log  /var/log/nginx/access.log  proxy;
    open_log_file_cache off;
    upstream rabbitTcp {
        server 10.0.3.133:5672;
        server 10.0.3.134:5672;
        server 10.0.3.135:5672;
    }
    server {
        listen 5672;
        proxy_connect_timeout 5s;
        proxy_timeout 30s;
        proxy_pass rabbitTcp;
    }
    include /etc/nginx/conf.d/*.stream;
}
EOF

rabbitmq的服务管理文件(网络直接使用宿主机的)

节点一(10.0.3.133)
shell 复制代码
  mkdir -p /usr/yunji/rabbitmq-server
  cat > /usr/yunji/rabbitmq-server/docker-compose.yml << EOF
  # Copyright Broadcom, Inc. All Rights Reserved.
  # SPDX-License-Identifier: APACHE-2.0
  
  version: '2'
  
  services:
    rabbitmq:
      image: docker.io/bitnami/rabbitmq
      container_name: rabbitmq01
  #    ports:
  #      - '4369:4369'
  #      - '5551:5551'
  #      - '5552:5552'
  #      - '5672:5672'
  #      - '25672:25672'
  #      - '15672:15672'
      network_mode: "host"
      environment:
        - RABBITMQ_NODE_TYPE=stats
        - RABBITMQ_NODE_NAME=rabbit@rabbitmq01
        - RABBITMQ_ERL_COOKIE=s3cr3tc00ki3
  #      - RABBITMQ_SECURE_PASSWORD=yes
        - RABBITMQ_LOGS=-
      extra_hosts:
        - "rabbitmq01:10.0.3.133"
        - "rabbitmq02:10.0.3.134"
        - "rabbitmq03:10.0.3.135"
      volumes:
        - 'rabbitmq_data:/bitnami/rabbitmq/mnesia'
  volumes:
    rabbitmq_data:
      driver: local
  EOF	
节点二(10.0.3.134)
shell 复制代码
  mkdir -p /usr/yunji/rabbitmq-server
  cat > /usr/yunji/rabbitmq-server/docker-compose.yml << EOF
  # Copyright Broadcom, Inc. All Rights Reserved.
  # SPDX-License-Identifier: APACHE-2.0
  
  version: '2'
  
  services:
    rabbitmq:
      image: docker.io/bitnami/rabbitmq
      container_name: rabbitmq02
  #    ports:
  #      - '4369:4369'
  #      - '5551:5551'
  #      - '5552:5552'
  #      - '5672:5672'
  #      - '25672:25672'
  #      - '15672:15672'
      network_mode: "host"
      environment:
        - RABBITMQ_NODE_TYPE=queue-disc
        - RABBITMQ_NODE_NAME=rabbit@rabbitmq02
        - RABBITMQ_CLUSTER_NODE_NAME=rabbit@rabbitmq01
        - RABBITMQ_ERL_COOKIE=s3cr3tc00ki3
  #      - RABBITMQ_SECURE_PASSWORD=yes
        - RABBITMQ_LOGS=-
      extra_hosts:
        - "rabbitmq01:10.0.3.133"
        - "rabbitmq02:10.0.3.134"
        - "rabbitmq03:10.0.3.135"
      volumes:
        - 'rabbitmq_data:/bitnami/rabbitmq/mnesia'
  volumes:
    rabbitmq_data:
      driver: local
  EOF	
节点三(10.0.3.135)
shell 复制代码
  mkdir -p /usr/yunji/rabbitmq-server
  cat > /usr/yunji/rabbitmq-server/docker-compose.yml << EOF
  # Copyright Broadcom, Inc. All Rights Reserved.
  # SPDX-License-Identifier: APACHE-2.0
  
  version: '2'
  
  services:
    rabbitmq:
      image: docker.io/bitnami/rabbitmq
      container_name: rabbitmq03
  #    ports:
  #      - '4369:4369'
  #      - '5551:5551'
  #      - '5552:5552'
  #      - '5672:5672'
  #      - '25672:25672'
  #      - '15672:15672'
      network_mode: "host"
      environment:
        - RABBITMQ_NODE_TYPE=queue-ram
        - RABBITMQ_NODE_NAME=rabbit@rabbitmq03
        - RABBITMQ_CLUSTER_NODE_NAME=rabbit@rabbitmq01
        - RABBITMQ_ERL_COOKIE=s3cr3tc00ki3
  #      - RABBITMQ_SECURE_PASSWORD=yes
        - RABBITMQ_LOGS=-
      extra_hosts:
        - "rabbitmq01:10.0.3.133"
        - "rabbitmq02:10.0.3.134"
        - "rabbitmq03:10.0.3.135"
      volumes:
        - 'rabbitmq_data:/bitnami/rabbitmq/mnesia'
  volumes:
    rabbitmq_data:
      driver: local
  EOF	

起服务

rabbitmq服务启动

节点一(10.0.3.133)

shell 复制代码
cd /usr/yunji/rabbitmq-server
docker-compose -f docker-compose.yml up -d --no-deps

节点二(10.0.3.134)

shell 复制代码
  cd /usr/yunji/rabbitmq-server
  docker-compose -f docker-compose.yml up -d --no-deps

节点三(10.0.3.135)

shell 复制代码
  cd /usr/yunji/rabbitmq-server
  docker-compose -f docker-compose.yml up -d --no-deps

验证集群是否成功

使用浏览器访问url: http://10.0.3.133:15672,确认节点是否都可以看到;如果是,则确认集群成功。

用户授权参考如下链接内容
RabbitMQ3.13.x之四_RabbitMQ角色说明及创建用户与授权

nginx负载服务启动

shell 复制代码
  cd /usr/yunji/nginx_4_lsb/
  docker-compose -f docker-compose.yml up -d --no-deps

测试

  • 单点直连rabbitmq的第一个节点压测测试

    shell 复制代码
      docker run -it --rm pivotalrabbitmq/perf-test:latest -h "amqp://admin:[email protected]:5672" -x 2 -y 4 -u "perf-test1" -a --id "test1" -s 4000

    结果:

  • 单点直连rabbitmq的三个节点压测测试

    shell 复制代码
      docker run -it --rm pivotalrabbitmq/perf-test:latest -H "amqp://admin:[email protected]:5672,amqp://admin:[email protected]:5672,amqp://admin:[email protected]:5672" -x 2 -y 4 -u "perf-test1" -a --id "test1" -s 4000

    结果:

  • 单点直连nginx负载的压测测试

    shell 复制代码
      docker run -it --rm pivotalrabbitmq/perf-test:latest -h "amqp://admin:[email protected]:5672" -x 2 -y 4 -u "perf-test1" -a --id "test1" -s 4000

结果

增加nginx负载均衡的能力,实现了流量负载的能力,确实可以解决单节点负载的问题。

问题和思考

  • rabbitmq节点宕机一个之后,该节点得到的消息是否仍然可以消费?

    • 答: 否,由于当前的消息仍然是放在接收的节点上,只有其他节点主动获取消息,其他rabbitmq才能让消费端消费数据。
  • nginx单点部署,是否存在单点故障的问题

    • 答: 是,由于单点部署,无法保证该负载出现服务异常之后的后端服务对外提供服务的能力,还需要其他例如keepalive等服务补充支持
  • 后端一个rabbitmq的节点宕机,nginx是否可以感知到,并且将后续的消息转向另外的节点?

    • 答:需要配置文件里面设置链接超时的内容,然后nginx会依照超时的重试间隔和重试时间进行重连接,这个可能会导致部分业务出现链接异常的问题。所以还需要通过其他配置或者服务补充支持该异常的处理情况。
  • rabbitmq节点宕机一个之后,该节点得到的消息是否仍然可以消费?

    • 答: 否,由于当前的消息仍然是放在接收的节点上,只有其他节点主动获取消息,其他rabbitmq才能让消费端消费数据。
  • nginx单点部署,是否存在单点故障的问题

    • 答: 是,由于单点部署,无法保证该负载出现服务异常之后的后端服务对外提供服务的能力,还需要其他例如keepalive等服务补充支持
  • 后端一个rabbitmq的节点宕机,nginx是否可以感知到,并且将后续的消息转向另外的节点?

    • 需要配置文件里面设置链接超时的内容,然后nginx会依照超时的重试间隔和重试时间进行重连接,这个可能会导致部分业务出现链接异常的问题。所以还需要通过其他配置或者服务补充支持该异常的处理情况。
相关推荐
RainbowSea15 小时前
6. RabbitMQ 死信队列的详细操作编写
java·消息队列·rabbitmq
RainbowSea15 小时前
5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
java·消息队列·rabbitmq
数据智能老司机16 小时前
CockroachDB权威指南——CockroachDB SQL
数据库·分布式·架构
数据智能老司机16 小时前
CockroachDB权威指南——开始使用
数据库·分布式·架构
数据智能老司机17 小时前
CockroachDB权威指南——CockroachDB 架构
数据库·分布式·架构
IT成长日记17 小时前
【Kafka基础】Kafka工作原理解析
分布式·kafka
xujiangyan_19 小时前
nginx的反向代理和负载均衡
服务器·网络·nginx
州周19 小时前
kafka副本同步时HW和LEO
分布式·kafka
ChinaRainbowSea20 小时前
1. 初始 RabbitMQ 消息队列
java·中间件·rabbitmq·java-rabbitmq
爱的叹息21 小时前
主流数据库的存储引擎/存储机制的详细对比分析,涵盖关系型数据库、NoSQL数据库和分布式数据库
数据库·分布式·nosql