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:admin@10.0.3.133: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:admin@10.0.3.133:5672,amqp://admin:admin@10.0.3.134:5672,amqp://admin:admin@10.0.3.135: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:admin@10.0.3.132: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会依照超时的重试间隔和重试时间进行重连接,这个可能会导致部分业务出现链接异常的问题。所以还需要通过其他配置或者服务补充支持该异常的处理情况。
相关推荐
不能再留遗憾了1 小时前
RabbitMQ 高级特性——消息分发
分布式·rabbitmq·ruby
茶馆大橘1 小时前
微服务系列六:分布式事务与seata
分布式·docker·微服务·nacos·seata·springcloud
材料苦逼不会梦到计算机白富美4 小时前
golang分布式缓存项目 Day 1
分布式·缓存·golang
想进大厂的小王4 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
Java 第一深情4 小时前
高性能分布式缓存Redis-数据管理与性能提升之道
redis·分布式·缓存
许苑向上5 小时前
【零基础小白】 window环境下安装RabbitMQ
rabbitmq
ZHOU西口6 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
zmd-zk6 小时前
kafka+zookeeper的搭建
大数据·分布式·zookeeper·中间件·kafka
ajsbxi8 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
yx9o11 小时前
Kafka 源码 KRaft 模式本地运行
分布式·kafka