原创

两层、三层nginx百万级QPS设计

温馨提示:
本文最后更新于 2025年09月28日,已超过 257 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我


启动命令:最后的参数可以将前端项目直接复制到 nginx节点中,无此参数 则直接生成默认的主页,以便区分 节点

./cn 2 3 80 /data/configs  /root/dist


两层、三层nginx百万级QPS设计     可以搭建2层、3层nginx,并直接将 前端项目 打包进 最后一层 nginx中 

#!/bin/bash
# 在脚本一开始启用日志记录
exec &> >(tee -a Nginx_Architecture.log)

# 颜色定义 - 扩展颜色数组以支持更多节点
declare -a colors=("red" "blue" "green" "orange" "purple" "cyan" "yellow" "pink" "lightblue" "lightgreen" "lavender" "coral")

# HTML目录定义
HTML_DIR="html"

# 添加层级选择对话框
echo "请输入您要创建的nginx层级,2 代表2层,3 代表3层:"
read -p "请选择架构层级 (2/3): " NGINX_LEVEL

# 验证输入
if [[ "$NGINX_LEVEL" != "2" && "$NGINX_LEVEL" != "3" ]]; then
  echo "Error: 请输入有效的层级 (2 或 3)"
  exit 1
fi

# 参数处理
if [ $# -gt 5 ]; then
  echo "Usage: $0 [cluster_size] [lb_cluster_size] [host_port] [config_dir] [source_dir]"
  echo "  cluster_size:     后端节点数量 (默认: 3)"
  echo "  lb_cluster_size:  负载均衡器数量 (最小: 1)"
  echo "  host_port:        暴露的主机端口 (默认: 8080)"
  echo "  config_dir:       配置文件存储目录 (默认: ./nginx-configs)"
  echo "  source_dir:       要复制到从节点的源文件夹路径"
  exit 1
fi

# 参数解析
CLUSTER_SIZE=${1:-3}
LB_CLUSTER_SIZE=${2:-2}
HOST_PORT=${3:-8080}
CONFIG_DIR=${4:-./nginx-configs}
SOURCE_DIR=${5}

# 参数验证
if ! [[ "$CLUSTER_SIZE" =~ ^[0-9]+$ ]] || [ "$CLUSTER_SIZE" -le 0 ]; then
  echo "Error: Cluster size must be a positive integer"
  exit 1
fi

if ! [[ "$LB_CLUSTER_SIZE" =~ ^[0-9]+$ ]] || [ "$LB_CLUSTER_SIZE" -lt 1 ]; then
  echo "Error: Load balancer cluster size must be at least 1"
  exit 1
fi

if ! [[ "$HOST_PORT" =~ ^[0-9]+$ ]] || [ "$HOST_PORT" -lt 1024 ] || [ "$HOST_PORT" -gt 65535 ]; then
  echo "Error: Port must be between 1024 and 65535"
  exit 1
fi

# 路径验证
if [ -e "$CONFIG_DIR" ] && [ ! -d "$CONFIG_DIR" ]; then
  echo "Error: Config path exists but is not a directory"
  exit 1
fi

# 验证源目录(如果提供)
if [ -n "$SOURCE_DIR" ] && [ ! -d "$SOURCE_DIR" ]; then
  echo "Error: Source directory does not exist or is not a directory"
  exit 1
fi

# 网络配置
NETWORK_NAME=nginx-cluster

# 创建配置目录
mkdir -p "$CONFIG_DIR"
CONFIG_ROOT=$(cd "$CONFIG_DIR" && pwd)

# 文件定义
MAIN_CONF="nginx.conf"
LB_DIR="lb"
BUS_DIR="bus"

# 清理旧资源
echo "清理旧资源..."
docker rm -f nginx-node-* nginx-lb-* nginx-bus 2>/dev/null
docker network rm $NETWORK_NAME 2>/dev/null
rm -rf "$CONFIG_ROOT"
mkdir -p "$CONFIG_ROOT"

# 创建自定义网络
echo "创建自定义网络..."
docker network create -d bridge --subnet=192.168.1.0/24 $NETWORK_NAME 2>/dev/null

# 生成主配置文件 - 百万级QPS优化版本
cat <<'EOF' > "$CONFIG_ROOT/$MAIN_CONF"
user  nginx;
worker_processes  auto;

# 增加最大打开文件数限制
worker_rlimit_nofile 100000;

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

events {
    # 优化事件处理模型
    use epoll;
    worker_connections  20000;
    multi_accept on;
}

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"';

    # 高并发优化设置
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;

    # 缓冲区优化
    client_body_buffer_size     128k;
    client_max_body_size        10m;
    client_header_buffer_size   1k;
    large_client_header_buffers 4 4k;
    output_buffers              1 32k;
    postpone_output             1460;

    # 超时优化
    client_header_timeout  3m;
    client_body_timeout    3m;
    send_timeout           3m;
    keepalive_timeout      30;
    keepalive_requests     1000;

    # Gzip 压缩优化
    gzip  on;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;

    # 文件缓存优化
    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    # 代理优化
    proxy_buffering on;
    proxy_buffer_size 4k;
    proxy_buffers 8 4k;
    proxy_busy_buffers_size 8k;
    proxy_temp_file_write_size 32k;

    # 关闭访问日志提升性能(生产环境中可选择性开启)
    access_log off;

    include /etc/nginx/conf.d/*.conf;
}
EOF

# 启动后端节点
for i in $(seq 1 $CLUSTER_SIZE); do
  # 创建节点目录结构
  NODE_DIR="$CONFIG_ROOT/node-$i"
  mkdir -p "$NODE_DIR/conf.d" "$NODE_DIR/$HTML_DIR"

  # 如果提供了源目录,则复制文件到HTML目录
  if [ -n "$SOURCE_DIR" ]; then
    cp -r "$SOURCE_DIR"/* "$NODE_DIR/$HTML_DIR/" 2>/dev/null || echo "Warning: Failed to copy files from $SOURCE_DIR"
  else
    # 生成节点页面
    # 使用模运算确保颜色索引不会超出范围
    COLOR_INDEX=$(( (i-1) % ${#colors[@]} ))
    cat <<EOF > "$NODE_DIR/$HTML_DIR/index.html"
<!DOCTYPE html>
<html>
<head><title>Node $i</title></head>
<body style="background-color:${colors[$COLOR_INDEX]}">
<h1>Node $i</h1>
<p>Backend Server</p>
<p>Container ID: Placeholder</p>
</body>
</html>
EOF
  fi

  # 生成节点配置文件 - 百万级QPS优化版本
  cat <<EOF > "$NODE_DIR/conf.d/default.conf"
server {
    listen 80 reuseport;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files \$uri \$uri/ =404;

        # 静态文件优化
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
EOF

  # 先尝试停止并删除可能存在的容器
  docker stop nginx-node-$i 2>/dev/null
  docker rm nginx-node-$i 2>/dev/null

  # 启动容器(使用自定义网络)- 添加系统优化参数
  if docker run -d \
    --name nginx-node-$i \
    --network $NETWORK_NAME \
    --ip 192.168.1.$((i+10)) \
    --ulimit nofile=100000:100000 \
    -v "$NODE_DIR/conf.d:/etc/nginx/conf.d" \
    -v "$NODE_DIR/$HTML_DIR:/usr/share/nginx/html" \
    -v "$CONFIG_ROOT/$MAIN_CONF:/etc/nginx/nginx.conf" \
    nginx:latest nginx -g 'daemon off;'; then
    echo "成功启动 nginx-node-$i"

    # 显示容器IP
    CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-node-$i 2>/dev/null)
    if [ -n "$CONTAINER_IP" ]; then
      echo "容器IP: $CONTAINER_IP"
    fi
  else
    echo "警告: 容器 nginx-node-$i 启动失败"
  fi
done

# 创建负载均衡器配置
mkdir -p "$CONFIG_ROOT/$LB_DIR/conf.d"
LB_CONF="$CONFIG_ROOT/$LB_DIR/conf.d/default.conf"

# 生成负载均衡配置 - 百万级QPS优化版本
cat <<EOF > $LB_CONF
upstream backend {
    least_conn;
    keepalive 1000;
    keepalive_requests 10000;
    keepalive_time 300s;
$(for i in $(seq 1 $CLUSTER_SIZE); do echo "    server nginx-node-$i:80 max_fails=3 fail_timeout=30s;"; done)
}

server {
    listen 80 reuseport;

    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_cache_bypass \$http_upgrade;

        # 代理超时优化
        proxy_connect_timeout 5s;
        proxy_send_timeout 10s;
        proxy_read_timeout 10s;
    }

    location /_status {
        stub_status on;
        access_log off;
        allow all;
    }
}
EOF

# 启动负载均衡器集群
for i in $(seq 1 $LB_CLUSTER_SIZE); do
  # 先尝试停止并删除可能存在的容器
  docker stop nginx-lb-$i 2>/dev/null
  docker rm nginx-lb-$i 2>/dev/null

  # 启动容器(使用自定义网络)- 添加系统优化参数
  if docker run -d \
    --name nginx-lb-$i \
    --network $NETWORK_NAME \
    --ip 192.168.1.$((252-i)) \
    -p $((HOST_PORT+i-1)):80 \
    --ulimit nofile=100000:100000 \
    -v "$CONFIG_ROOT/lb/conf.d:/etc/nginx/conf.d" \
    -v "$CONFIG_ROOT/$MAIN_CONF:/etc/nginx/nginx.conf" \
    nginx:latest nginx -g 'daemon off;'; then
    echo "成功启动 nginx-lb-$i"

    # 显示容器IP
    CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-lb-$i 2>/dev/null)
    if [ -n "$CONTAINER_IP" ]; then
      echo "容器IP: $CONTAINER_IP"
    fi
  else
    echo "警告: 容器 nginx-lb-$i 启动失败"
  fi
done

# 根据选择的架构层级决定是否创建总线nginx
if [ "$NGINX_LEVEL" = "3" ]; then
  # 添加总线nginx端口输入对话框
  while true; do
    read -p "总线nginx对外暴露的端口: " BUS_PORT

    # 验证端口输入
    if ! [[ "$BUS_PORT" =~ ^[0-9]+$ ]] || [ "$BUS_PORT" -lt 1024 ] || [ "$BUS_PORT" -gt 65535 ]; then
      echo "Error: 端口必须是1024到65535之间的数字"
      continue
    fi

    # 检查端口是否被占用
    if netstat -tuln | grep -q ":$BUS_PORT "; then
      echo "Error: 端口 $BUS_PORT 已被占用,请重新输入"
      continue
    else
      echo "端口 $BUS_PORT 可用"
      break
    fi
  done

  # 创建总线nginx配置
  mkdir -p "$CONFIG_ROOT/$BUS_DIR/conf.d"
  BUS_CONF="$CONFIG_ROOT/$BUS_DIR/conf.d/default.conf"

  # 生成总线nginx配置,负载均衡到所有负载均衡器节点 - 百万级QPS优化版本
  cat <<EOF > $BUS_CONF
upstream loadbalancers {
    least_conn;
    keepalive 1000;
    keepalive_requests 10000;
    keepalive_time 300s;
$(for i in $(seq 1 $LB_CLUSTER_SIZE); do echo "    server nginx-lb-$i:80 max_fails=3 fail_timeout=30s;"; done)
}

server {
    listen 80 reuseport;

    location / {
        proxy_pass http://loadbalancers;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_cache_bypass \$http_upgrade;

        # 代理超时优化
        proxy_connect_timeout 5s;
        proxy_send_timeout 10s;
        proxy_read_timeout 10s;
    }
}
EOF

  # 启动总线nginx容器
  docker stop nginx-bus 2>/dev/null
  docker rm nginx-bus 2>/dev/null

  # 启动总线nginx容器(使用自定义网络)- 添加系统优化参数
  if docker run -d \
    --name nginx-bus \
    --network $NETWORK_NAME \
    --ip 192.168.1.254 \
    -p $BUS_PORT:80 \
    --ulimit nofile=100000:100000 \
    -v "$CONFIG_ROOT/bus/conf.d:/etc/nginx/conf.d" \
    -v "$CONFIG_ROOT/$MAIN_CONF:/etc/nginx/nginx.conf" \
    nginx:latest nginx -g 'daemon off;'; then
    echo "成功启动 nginx-bus"

    # 显示总线nginx容器IP
    BUS_CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-bus 2>/dev/null)
    if [ -n "$BUS_CONTAINER_IP" ]; then
      echo "容器IP: $BUS_CONTAINER_IP"
    fi
  else
    echo "警告: 容器 nginx-bus 启动失败"
  fi
fi

# 等待容器初始化
sleep 3

# 更新页面中的容器ID
for i in $(seq 1 $CLUSTER_SIZE); do
  if docker ps | grep -q "nginx-node-$i"; then
    CONTAINER_ID=$(docker inspect --format='{{.Id}}' nginx-node-$i | cut -c1-12)
    sed -i "s/Placeholder/$CONTAINER_ID/" "$CONFIG_ROOT/node-$i/$HTML_DIR/index.html"
    docker cp "$CONFIG_ROOT/node-$i/$HTML_DIR/index.html" nginx-node-$i:/usr/share/nginx/html/index.html 2>/dev/null
  fi
done

# 输出信息
echo "✅ 百万级QPS优化的负载均衡集群已启动"
echo "配置目录: $CONFIG_ROOT"
echo "后端集群规模: $CLUSTER_SIZE 节点"
echo "负载均衡器集群规模: $LB_CLUSTER_SIZE 实例"
if [ "$NGINX_LEVEL" = "3" ]; then
  echo "架构层级: 3层 (包含总线nginx)"
  echo "总线nginx地址: http://$(hostname):$BUS_PORT"
else
  echo "架构层级: 2层 (不包含总线nginx)"
fi
echo "访问地址: http://$(hostname):$HOST_PORT (端口映射: $HOST_PORT->$((HOST_PORT+LB_CLUSTER_SIZE-1)))"
if [ -n "$SOURCE_DIR" ]; then
  echo "源文件目录: $SOURCE_DIR"
fi
echo "节点样式:"
for i in $(seq 1 $CLUSTER_SIZE); do
  COLOR_INDEX=$(( (i-1) % ${#colors[@]} ))
  echo "Node $i -> 背景颜色: ${colors[$COLOR_INDEX]}"
done


特点  

这个脚本 `nginx3层架构_百万级QPS优化.bash` 是一个用于构建高性能 Nginx 集群的自动化部署脚本,支持构建 2 层或 3 层架构,旨在实现百万级 QPS 的性能优化。

## ? 脚本功能概述

- 支持构建 2 层或 3 层 Nginx 集群架构
- 自动创建 Docker 容器和自定义网络
- 配置高性能 Nginx 参数(适用于百万级 QPS 场景)
- 自动生成 HTML 页面用于测试和展示
- 支持自定义源文件目录复制到节点中

## ? 使用方法

```bash
./nginx3层架构_百万级QPS优化.bash [cluster_size] [lb_cluster_size] [host_port] [config_dir] [source_dir]
```


### 参数说明

| 参数名 | 说明 | 默认值 |
|--------|------|--------|
| `cluster_size` | 后端节点数量 | 3 |
| `lb_cluster_size` | 负载均衡器数量 | 2 |
| `host_port` | 暴露的主机端口(起始端口) | 8080 |
| `config_dir` | 配置文件存储目录 | ./nginx-configs |
| `source_dir` | 要复制到从节点的源文件夹路径 | 无 |

### 示例

```bash
# 基本使用,默认参数
./nginx3层架构_百万级QPS优化.bash

# 自定义参数:5个后端节点,3个负载均衡器,起始端口9000
./nginx3层架构_百万级QPS优化.bash 5 3 9000 ./my-configs ./web-content
```


## ?️ 运行时交互

脚本运行时会提示用户输入以下信息:

1. **架构层级选择**:
   - 输入 `2` 表示构建 2 层架构(客户端 -> 负载均衡器 -> 后端节点)
   - 输入 `3` 表示构建 3 层架构(客户端 -> 总线nginx -> 负载均衡器 -> 后端节点)

2. **总线nginx端口(仅3层架构时)**:
   - 如果选择 3 层架构,需要输入总线 nginx 对外暴露的端口号

## ? 目录结构

脚本会自动生成以下目录结构:

```
nginx-configs/
├── nginx.conf              # 主配置文件
├── lb/                     # 负载均衡器配置
│   └── conf.d/
│       └── default.conf
├── bus/                    # 总线nginx配置(仅3层架构)
│   └── conf.d/
│       └── default.conf
└── node-X/                 # 每个后端节点的配置
    ├── conf.d/
    │   └── default.conf
    └── html/
        └── index.html
```


## ? 访问方式

- **2层架构**:直接通过 `http://<host>:<host_port>` 访问
- **3层架构**:通过 `http://<host>:<bus_port>` 访问

## ⚠️ 注意事项

1. 确保 Docker 服务正在运行
2. 确保指定的端口未被占用
3. 脚本会自动清理之前的容器和网络配置
4. 如需生产环境使用,建议根据实际需求调整配置参数

## ? 输出信息

脚本执行完成后会显示:
- 集群配置信息
- 访问地址
- 各节点的背景颜色
- 容器IP地址等详细信息

日志会被记录在 `Nginx_Architecture.log` 文件中。

两层nginx百万级QPS设计

#!/bin/bash

# 颜色定义 - 扩展颜色数组以支持更多节点
declare -a colors=("red" "blue" "green" "orange" "purple" "cyan" "yellow" "pink" "lightblue" "lightgreen" "lavender" "coral")

# HTML目录定义
HTML_DIR="html"

# 参数处理
if [ $# -gt 5 ]; then
  echo "Usage: $0 [cluster_size] [lb_cluster_size] [host_port] [config_dir] [source_dir]"
  echo "  cluster_size:     后端节点数量 (默认: 3)"
  echo "  lb_cluster_size:  负载均衡器数量 (最小: 1)"
  echo "  host_port:        暴露的主机端口 (默认: 8080)"
  echo "  config_dir:       配置文件存储目录 (默认: ./nginx-configs)"
  echo "  source_dir:       要复制到从节点的源文件夹路径"
  exit 1
fi

# 参数解析
CLUSTER_SIZE=${1:-3}
LB_CLUSTER_SIZE=${2:-2}
HOST_PORT=${3:-8080}
CONFIG_DIR=${4:-./nginx-configs}
SOURCE_DIR=${5}

# 参数验证
if ! [[ "$CLUSTER_SIZE" =~ ^[0-9]+$ ]] || [ "$CLUSTER_SIZE" -le 0 ]; then
  echo "Error: Cluster size must be a positive integer"
  exit 1
fi

if ! [[ "$LB_CLUSTER_SIZE" =~ ^[0-9]+$ ]] || [ "$LB_CLUSTER_SIZE" -lt 1 ]; then
  echo "Error: Load balancer cluster size must be at least 1"
  exit 1
fi

if ! [[ "$HOST_PORT" =~ ^[0-9]+$ ]] || [ "$HOST_PORT" -lt 1024 ] || [ "$HOST_PORT" -gt 65535 ]; then
  echo "Error: Port must be between 1024 and 65535"
  exit 1
fi

# 路径验证
if [ -e "$CONFIG_DIR" ] && [ ! -d "$CONFIG_DIR" ]; then
  echo "Error: Config path exists but is not a directory"
  exit 1
fi

# 验证源目录(如果提供)
if [ -n "$SOURCE_DIR" ] && [ ! -d "$SOURCE_DIR" ]; then
  echo "Error: Source directory does not exist or is not a directory"
  exit 1
fi

# 网络配置
NETWORK_NAME=nginx-cluster

# 创建配置目录
mkdir -p "$CONFIG_DIR"
CONFIG_ROOT=$(cd "$CONFIG_DIR" && pwd)

# 文件定义
MAIN_CONF="nginx.conf"
LB_DIR="lb"

# 清理旧资源
echo "清理旧资源..."
docker rm -f nginx-node-* nginx-lb-* 2>/dev/null
docker network rm $NETWORK_NAME 2>/dev/null
rm -rf "$CONFIG_ROOT"
mkdir -p "$CONFIG_ROOT"

# 创建自定义网络
echo "创建自定义网络..."
docker network create -d bridge --subnet=192.168.1.0/24 $NETWORK_NAME 2>/dev/null

# 生成主配置文件 - 百万级QPS优化配置
cat <<'EOF' > "$CONFIG_ROOT/$MAIN_CONF"
user  nginx;
worker_processes  auto;

# 绑定worker进程到CPU核心
worker_cpu_affinity auto;

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

# 调整worker_connections以支持高并发
events {
    use epoll;
    worker_connections  65535;
    multi_accept on;
}

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  off;  # 关闭访问日志以提高性能
    error_log   /var/log/nginx/error.log crit;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    
    # 调整超时设置以优化性能
    keepalive_timeout  30;
    keepalive_requests 1000;
    
    # Gzip 设置 - 优化压缩级别
    gzip  on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_proxied expired no-cache no-store private must-revalidate auth;
    gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss;
    gzip_comp_level 1;

    # 设置缓冲区以处理更多请求
    client_body_buffer_size 128k;
    client_max_body_size 50m;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 4k;
    output_buffers 1 32k;
    postpone_output 1460;
    
    # 设置文件缓存
    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    
    # 设置连接处理优化
    reset_timedout_connection on;
    
    # 设置请求限制
    limit_req_zone $binary_remote_addr zone=general:10m rate=1000r/s;
    
    include /etc/nginx/conf.d/*.conf;
}
EOF

# 启动后端节点
for i in $(seq 1 $CLUSTER_SIZE); do
  # 创建节点目录结构
  NODE_DIR="$CONFIG_ROOT/node-$i"
  mkdir -p "$NODE_DIR/conf.d" "$NODE_DIR/$HTML_DIR"
  
  # 如果提供了源目录,则复制文件到HTML目录
  if [ -n "$SOURCE_DIR" ]; then
    cp -r "$SOURCE_DIR"/* "$NODE_DIR/$HTML_DIR/" 2>/dev/null || echo "Warning: Failed to copy files from $SOURCE_DIR"
  else
    # 生成节点页面
    # 使用模运算确保颜色索引不会超出范围
    COLOR_INDEX=$(( (i-1) % ${#colors[@]} ))
    cat <<EOF > "$NODE_DIR/$HTML_DIR/index.html"
<!DOCTYPE html>
<html>
<head><title>Node $i</title></head>
<body style="background-color:${colors[$COLOR_INDEX]}">
<h1>Node $i</h1>
<p>Backend Server</p>
<p>Container ID: Placeholder</p>
</body>
</html>
EOF
  fi
  
  # 生成节点配置文件 - 百万级QPS优化配置
  cat <<EOF > "$NODE_DIR/conf.d/default.conf"
server {
    listen 80 reuseport;
    
    # 应用请求限制
    # limit_req zone=general burst=200 nodelay;
    
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files \$uri \$uri/ =404;
        
        # 启用缓存头
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
EOF

  # 先尝试停止并删除可能存在的容器
  docker stop nginx-node-$i 2>/dev/null
  docker rm nginx-node-$i 2>/dev/null
  
  # 启动容器(使用自定义网络)
  # 修改IP地址分配,避免与负载均衡器冲突
  if docker run -d \
    --name nginx-node-$i \
    --network $NETWORK_NAME \
    --ip 192.168.1.$((i+10)) \
    --ulimit nofile=1000000:1000000 \  # 设置文件描述符限制
    -v "$NODE_DIR/conf.d:/etc/nginx/conf.d" \
    -v "$NODE_DIR/$HTML_DIR:/usr/share/nginx/html" \
    -v "$CONFIG_ROOT/$MAIN_CONF:/etc/nginx/nginx.conf" \
    nginx:latest; then
    echo "成功启动 nginx-node-$i"
  else
    echo "警告: 容器 nginx-node-$i 启动失败"
  fi
done

# 创建负载均衡器配置
mkdir -p "$CONFIG_ROOT/$LB_DIR/conf.d"
LB_CONF="$CONFIG_ROOT/$LB_DIR/conf.d/default.conf"

# 生成负载均衡配置 - 百万级QPS优化配置
cat <<EOF > $LB_CONF
upstream backend {
    least_conn;
    keepalive 32;
    keepalive_requests 1000;
    keepalive_timeout 30s;
$(for i in $(seq 1 $CLUSTER_SIZE); do echo "    server nginx-node-$i:80;"; done)
}

server {
    listen 80 reuseport;

    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_cache_bypass \$http_upgrade;
        
        # 启用代理缓存
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 301 1h;
        proxy_cache_valid any 1m;
    }
    
    location /_status {
        stub_status on;
        access_log off;
        allow all;
    }
}
EOF

# 启动负载均衡器集群
for i in $(seq 1 $LB_CLUSTER_SIZE); do
  # 先尝试停止并删除可能存在的容器
  docker stop nginx-lb-$i 2>/dev/null
  docker rm nginx-lb-$i 2>/dev/null
  
  # 启动容器(使用自定义网络)
  # 修改IP地址分配,确保不会与后端节点冲突
  # 将负载均衡器的IP地址从100开始分配,避免冲突
  if docker run -d \
    --name nginx-lb-$i \
    --network $NETWORK_NAME \
    --ip 192.168.1.$((i+100)) \
    --ulimit nofile=1000000:1000000 \  # 设置文件描述符限制
    -p $((HOST_PORT+i-1)):80 \
    -v "$CONFIG_ROOT/lb/conf.d:/etc/nginx/conf.d" \
    -v "$CONFIG_ROOT/$MAIN_CONF:/etc/nginx/nginx.conf" \
    nginx:latest; then
    echo "成功启动 nginx-lb-$i"
  else
    echo "警告: 容器 nginx-lb-$i 启动失败"
  fi
done

# 等待容器初始化
sleep 3

# 更新页面中的容器ID
for i in $(seq 1 $CLUSTER_SIZE); do
  if docker ps | grep -q "nginx-node-$i"; then
    CONTAINER_ID=$(docker inspect --format='{{.Id}}' nginx-node-$i | cut -c1-12)
    sed -i "s/Placeholder/$CONTAINER_ID/" "$CONFIG_ROOT/node-$i/$HTML_DIR/index.html"
    docker cp "$CONFIG_ROOT/node-$i/$HTML_DIR/index.html" nginx-node-$i:/usr/share/nginx/html/index.html 2>/dev/null
  fi
done

# 输出信息
echo "✅ 基础负载均衡集群已启动"
echo "配置目录: $CONFIG_ROOT"
echo "后端集群规模: $CLUSTER_SIZE 节点"
echo "负载均衡器集群规模: $LB_CLUSTER_SIZE 实例"
echo "访问地址: http://$(hostname):$HOST_PORT (端口映射: $HOST_PORT->$((HOST_PORT+LB_CLUSTER_SIZE-1)))"
if [ -n "$SOURCE_DIR" ]; then
  echo "源文件目录: $SOURCE_DIR"
fi
echo "节点样式:"
for i in $(seq 1 $CLUSTER_SIZE); do
  COLOR_INDEX=$(( (i-1) % ${#colors[@]} ))
  echo "Node $i -> 背景颜色: ${colors[$COLOR_INDEX]}"
done


特点

这个优化后的脚本包含了以下百万级 QPS 优化措施:
主配置文件优化 (nginx.conf):
启用 worker_cpu_affinity 绑定工作进程到 CPU 核心
增加 worker_connections 到 65535
启用 epoll 事件模型和 multi_accept
关闭访问日志以提高性能
优化 keepalive 设置
调整 TCP 相关参数 (tcp_nopush, tcp_nodelay)
优化 Gzip 压缩设置
设置各种缓冲区大小
启用文件缓存
添加请求限制机制
容器启动优化:
设置 --ulimit nofile=1000000:1000000 增加文件描述符限制
启用 reuseport 选项提高性能
后端节点配置优化:
启用 reuseport
添加缓存头设置
负载均衡器配置优化:
启用 reuseport
优化 keepalive 相关设置
设置 proxy_set_header Connection "" 以启用 HTTP keep-alive
添加代理缓存配置
这些优化能够显著提升 Nginx 集群处理高并发请求的能力,使其更接近百万级 QPS 的性能要求。




2 | 3 层nginx创建  自定义ip分配

#!/bin/bash
# 在脚本一开始启用日志记录
exec &> >(tee -a Nginx_Architecture.log)
# 后端节点的ip偏移量
Node_Usage=2
# 负载节点的ip偏移量
Load_Usage=3
# 2层架构 是否加入nginx总线负载均衡
Add_Nginx_Bus=false
# 颜色定义 - 扩展颜色数组以支持更多节点
declare -a colors=("red" "blue" "green" "orange" "purple" "cyan" "yellow" "pink" "lightblue" "lightgreen" "lavender" "coral")

# HTML目录定义
HTML_DIR="html"

# 添加层级选择对话框
echo "请输入您要创建的nginx层级,2 代表2层,3 代表3层:"
read -p "请选择架构层级 (2/3): " NGINX_LEVEL

# 验证输入
if [[ "$NGINX_LEVEL" != "2" && "$NGINX_LEVEL" != "3" ]]; then
  echo "Error: 请输入有效的层级 (2 或 3)"
  exit 1
fi

# 参数处理
if [ $# -gt 5 ]; then
  echo "Usage: $0 [cluster_size] [lb_cluster_size] [host_port] [config_dir] [source_dir]"
  echo "  cluster_size:     后端节点数量 (默认: 3)"
  echo "  lb_cluster_size:  负载均衡器数量 (最小: 1)"
  echo "  host_port:        暴露的主机端口 (默认: 8080)"
  echo "  config_dir:       配置文件存储目录 (默认: ./nginx-configs)"
  echo "  source_dir:       要复制到从节点的源文件夹路径"
  exit 1
fi

# 参数解析
CLUSTER_SIZE=${1:-3}
LB_CLUSTER_SIZE=${2:-2}
HOST_PORT=${3:-8080}
CONFIG_DIR=${4:-./nginx-configs}
SOURCE_DIR=${5}

# 参数验证
if ! [[ "$CLUSTER_SIZE" =~ ^[0-9]+$ ]] || [ "$CLUSTER_SIZE" -le 0 ]; then
  echo "Error: Cluster size must be a positive integer"
  exit 1
fi

if ! [[ "$LB_CLUSTER_SIZE" =~ ^[0-9]+$ ]] || [ "$LB_CLUSTER_SIZE" -lt 1 ]; then
  echo "Error: Load balancer cluster size must be at least 1"
  exit 1
fi

if ! [[ "$HOST_PORT" =~ ^[0-9]+$ ]] || [ "$HOST_PORT" -lt 1024 ] || [ "$HOST_PORT" -gt 65535 ]; then
  echo "Error: Port must be between 1024 and 65535"
  exit 1
fi

# 路径验证
if [ -e "$CONFIG_DIR" ] && [ ! -d "$CONFIG_DIR" ]; then
  echo "Error: Config path exists but is not a directory"
  exit 1
fi

# 验证源目录(如果提供)
if [ -n "$SOURCE_DIR" ] && [ ! -d "$SOURCE_DIR" ]; then
  echo "Error: Source directory does not exist or is not a directory"
  exit 1
fi

# 网络配置
NETWORK_NAME=nginx-cluster

# 创建配置目录
mkdir -p "$CONFIG_DIR"
CONFIG_ROOT=$(cd "$CONFIG_DIR" && pwd)

# 文件定义
MAIN_CONF="nginx.conf"
LB_DIR="lb"
BUS_DIR="bus"

# 清理旧资源
echo "清理旧资源..."
docker rm -f nginx-node-* nginx-lb-* nginx-bus 2>/dev/null
docker network rm $NETWORK_NAME 2>/dev/null
rm -rf "$CONFIG_ROOT"
mkdir -p "$CONFIG_ROOT"

# 创建自定义网络
echo "创建自定义网络..."
docker network create -d bridge --subnet=192.168.1.0/24 $NETWORK_NAME 2>/dev/null

# 生成主配置文件 - 百万级QPS优化版本
cat <<'EOF' > "$CONFIG_ROOT/$MAIN_CONF"
user  nginx;
worker_processes  auto;

# 增加最大打开文件数限制
worker_rlimit_nofile 100000;

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

events {
    # 优化事件处理模型
    use epoll;
    worker_connections  20000;
    multi_accept on;
}

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"';

    # 高并发优化设置
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;

    # 缓冲区优化
    client_body_buffer_size     128k;
    client_max_body_size        10m;
    client_header_buffer_size   1k;
    large_client_header_buffers 4 4k;
    output_buffers              1 32k;
    postpone_output             1460;

    # 超时优化
    client_header_timeout  3m;
    client_body_timeout    3m;
    send_timeout           3m;
    keepalive_timeout      30;
    keepalive_requests     1000;

    # Gzip 压缩优化
    gzip  on;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;

    # 文件缓存优化
    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    # 代理优化
    proxy_buffering on;
    proxy_buffer_size 4k;
    proxy_buffers 8 4k;
    proxy_busy_buffers_size 8k;
    proxy_temp_file_write_size 32k;

    # 关闭访问日志提升性能(生产环境中可选择性开启)
    access_log off;

    include /etc/nginx/conf.d/*.conf;
}
EOF

# 启动后端节点
for i in $(seq 1 $CLUSTER_SIZE); do
  # 计算实际索引
  actual_index=$((i + Node_Usage))
  
  # 创建节点目录结构
  NODE_DIR="$CONFIG_ROOT/node-$actual_index"
  mkdir -p "$NODE_DIR/conf.d" "$NODE_DIR/$HTML_DIR"

  # 如果提供了源目录,则复制文件到HTML目录
  if [ -n "$SOURCE_DIR" ]; then
    cp -r "$SOURCE_DIR"/* "$NODE_DIR/$HTML_DIR/" 2>/dev/null || echo "Warning: Failed to copy files from $SOURCE_DIR"
  else
    # 生成节点页面
    # 使用模运算确保颜色索引不会超出范围
    COLOR_INDEX=$(( (actual_index-1) % ${#colors[@]} ))
    cat <<EOF > "$NODE_DIR/$HTML_DIR/index.html"
<!DOCTYPE html>
<html>
<head><title>Node $actual_index</title></head>
<body style="background-color:${colors[$COLOR_INDEX]}">
<h1>Node $actual_index</h1>
<p>Backend Server</p>
<p>Container ID: Placeholder</p>
</body>
</html>
EOF
  fi

  # 生成节点配置文件 - 百万级QPS优化版本
  cat <<EOF > "$NODE_DIR/conf.d/default.conf"
server {
    listen 80 reuseport;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files \$uri \$uri/ =404;

        # 静态文件优化
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
EOF

  # 先尝试停止并删除可能存在的容器
  docker stop nginx-node-$actual_index 2>/dev/null
  docker rm nginx-node-$actual_index 2>/dev/null

  # 启动容器(使用自定义网络)- 添加系统优化参数
  if docker run -d \
    --name nginx-node-$actual_index \
    --network $NETWORK_NAME \
    --ip 192.168.1.$((actual_index)) \
    --ulimit nofile=100000:100000 \
    -v "$NODE_DIR/conf.d:/etc/nginx/conf.d" \
    -v "$NODE_DIR/$HTML_DIR:/usr/share/nginx/html" \
    -v "$CONFIG_ROOT/$MAIN_CONF:/etc/nginx/nginx.conf" \
    nginx:latest nginx -g 'daemon off;'; then
    echo "成功启动 nginx-node-$actual_index"

    # 显示容器IP
    CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-node-$actual_index 2>/dev/null)
    if [ -n "$CONTAINER_IP" ]; then
      echo "容器IP: $CONTAINER_IP"
    fi
  else
    echo "警告: 容器 nginx-node-$actual_index 启动失败"
  fi
done

# 创建负载均衡器配置
mkdir -p "$CONFIG_ROOT/$LB_DIR/conf.d"
LB_CONF="$CONFIG_ROOT/$LB_DIR/conf.d/default.conf"

# 生成负载均衡配置 - 百万级QPS优化版本
cat <<EOF > $LB_CONF
upstream backend {
    least_conn;
    keepalive 1000;
    keepalive_requests 10000;
    keepalive_time 300s;
$(for i in $(seq 1 $CLUSTER_SIZE); do 
    actual_index=$((i + Node_Usage))
    echo "    server nginx-node-$actual_index:80 max_fails=3 fail_timeout=30s;"; 
done)
}

server {
    listen 80 reuseport;

    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_cache_bypass \$http_upgrade;

        # 代理超时优化
        proxy_connect_timeout 5s;
        proxy_send_timeout 10s;
        proxy_read_timeout 10s;
    }

    location /_status {
        stub_status on;
        access_log off;
        allow all;
    }
}
EOF

# 启动负载均衡器集群
for i in $(seq 1 $LB_CLUSTER_SIZE); do
  # 计算实际索引
  actual_index=$((i + Load_Usage))
  
  # 先尝试停止并删除可能存在的容器
  docker stop nginx-lb-$actual_index 2>/dev/null
  docker rm nginx-lb-$actual_index 2>/dev/null

  # 启动容器(使用自定义网络)- 添加系统优化参数
  if docker run -d \
    --name nginx-lb-$actual_index \
    --network $NETWORK_NAME \
    --ip 192.168.1.$((252-Load_Usage-i)) \
    -p $((HOST_PORT+i-1)):80 \
    --ulimit nofile=100000:100000 \
    -v "$CONFIG_ROOT/lb/conf.d:/etc/nginx/conf.d" \
    -v "$CONFIG_ROOT/$MAIN_CONF:/etc/nginx/nginx.conf" \
    nginx:latest nginx -g 'daemon off;'; then
    echo "成功启动 nginx-lb-$actual_index"

    # 显示容器IP
    CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-lb-$actual_index 2>/dev/null)
    if [ -n "$CONTAINER_IP" ]; then
      echo "容器IP: $CONTAINER_IP"
    fi
  else
    echo "警告: 容器 nginx-lb-$actual_index 启动失败"
  fi
done

# 根据选择的架构层级决定是否创建总线nginx
create_bus_nginx() {
  # 添加总线nginx端口输入对话框
  while true; do
    read -p "总线nginx对外暴露的端口: " BUS_PORT

    # 验证端口输入
    if ! [[ "$BUS_PORT" =~ ^[0-9]+$ ]] || [ "$BUS_PORT" -lt 1024 ] || [ "$BUS_PORT" -gt 65535 ]; then
      echo "Error: 端口必须是1024到65535之间的数字"
      continue
    fi

    # 检查端口是否被占用
    if netstat -tuln | grep -q ":$BUS_PORT "; then
      echo "Error: 端口 $BUS_PORT 已被占用,请重新输入"
      continue
    else
      echo "端口 $BUS_PORT 可用"
      break
    fi
  done

  # 创建总线nginx配置
  mkdir -p "$CONFIG_ROOT/$BUS_DIR/conf.d"
  BUS_CONF="$CONFIG_ROOT/$BUS_DIR/conf.d/default.conf"

  # 生成总线nginx配置,负载均衡到所有负载均衡器节点 - 百万级QPS优化版本
  cat <<EOF > $BUS_CONF
upstream loadbalancers {
    least_conn;
    keepalive 1000;
    keepalive_requests 10000;
    keepalive_time 300s;
$(for i in $(seq 1 $LB_CLUSTER_SIZE); do 
    actual_index=$((i + Load_Usage))
    echo "    server nginx-lb-$actual_index:80 max_fails=3 fail_timeout=30s;"; 
done)
}

server {
    listen 80 reuseport;

    location / {
        proxy_pass http://loadbalancers;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_cache_bypass \$http_upgrade;

        # 代理超时优化
        proxy_connect_timeout 5s;
        proxy_send_timeout 10s;
        proxy_read_timeout 10s;
    }
}
EOF

  # 启动总线nginx容器
  docker stop nginx-bus 2>/dev/null
  docker rm nginx-bus 2>/dev/null

  # 启动总线nginx容器(使用自定义网络)- 添加系统优化参数
  if docker run -d \
    --name nginx-bus \
    --network $NETWORK_NAME \
    --ip 192.168.1.254 \
    -p $BUS_PORT:80 \
    --ulimit nofile=100000:100000 \
    -v "$CONFIG_ROOT/bus/conf.d:/etc/nginx/conf.d" \
    -v "$CONFIG_ROOT/$MAIN_CONF:/etc/nginx/nginx.conf" \
    nginx:latest nginx -g 'daemon off;'; then
    echo "成功启动 nginx-bus"

    # 显示总线nginx容器IP
    BUS_CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-bus 2>/dev/null)
    if [ -n "$BUS_CONTAINER_IP" ]; then
      echo "容器IP: $BUS_CONTAINER_IP"
    fi
  else
    echo "警告: 容器 nginx-bus 启动失败"
  fi
}

# 判断是否需要创建总线nginx
should_create_bus=false

if [ "$NGINX_LEVEL" = "3" ]; then
  should_create_bus=true
elif [ "$NGINX_LEVEL" = "2" ] && [ "$Add_Nginx_Bus" = "true" ]; then
  should_create_bus=true
fi

if [ "$should_create_bus" = "true" ]; then
  create_bus_nginx
fi

# 等待容器初始化
sleep 3

# 更新页面中的容器ID
for i in $(seq 1 $CLUSTER_SIZE); do
  actual_index=$((i + Node_Usage))
  if docker ps | grep -q "nginx-node-$actual_index"; then
    CONTAINER_ID=$(docker inspect --format='{{.Id}}' nginx-node-$actual_index | cut -c1-12)
    sed -i "s/Placeholder/$CONTAINER_ID/" "$CONFIG_ROOT/node-$actual_index/$HTML_DIR/index.html"
    docker cp "$CONFIG_ROOT/node-$actual_index/$HTML_DIR/index.html" nginx-node-$actual_index:/usr/share/nginx/html/index.html 2>/dev/null
  fi
done

# 输出信息
echo "✅ 百万级QPS优化的负载均衡集群已启动"
echo "配置目录: $CONFIG_ROOT"
echo "后端集群规模: $CLUSTER_SIZE 节点"
echo "负载均衡器集群规模: $LB_CLUSTER_SIZE 实例"

if [ "$NGINX_LEVEL" = "3" ]; then
  echo "架构层级: 3层 (包含总线nginx)"
  echo "总线nginx地址: http://$(hostname):$BUS_PORT"
elif [ "$NGINX_LEVEL" = "2" ] && [ "$Add_Nginx_Bus" = "true" ]; then
  echo "架构层级: 2层 (包含总线nginx)"
  echo "总线nginx地址: http://$(hostname):$BUS_PORT"
else
  echo "架构层级: 2层 (不包含总线nginx)"
fi

echo "访问地址: http://$(hostname):$HOST_PORT (端口映射: $HOST_PORT->$((HOST_PORT+LB_CLUSTER_SIZE-1)))"
if [ -n "$SOURCE_DIR" ]; then
  echo "源文件目录: $SOURCE_DIR"
fi
echo "节点样式:"
for i in $(seq 1 $CLUSTER_SIZE); do
  actual_index=$((i + Node_Usage))
  COLOR_INDEX=$(( (actual_index-1) % ${#colors[@]} ))
  echo "Node $actual_index -> 背景颜色: ${colors[$COLOR_INDEX]}"
done


说明

根据提供的 [nginx_init.bash](file://C:\demo\src\main\resources\shell脚本\nginx集群\nginx_init.bash) 脚本内容,以下是该脚本的使用说明:

## 1. 脚本功能概述

这个脚本用于快速部署一个基于 Docker 的 Nginx 集群环境,支持构建 2 层或 3 层架构:
- **后端节点**:处理实际请求的 Nginx 服务器
- **负载均衡器**:负责将请求分发到后端节点
- **总线 Nginx(可选)**:在 3 层架构中作为统一入口,将请求转发给负载均衡器

## 2. 使用方法

### 基本命令格式
```bash
./nginx_init.bash [cluster_size] [lb_cluster_size] [host_port] [config_dir] [source_dir]
```


### 参数说明
| 参数名 | 默认值 | 描述 |
|--------|--------|------|
| `cluster_size` | 3 | 后端节点数量(正整数) |
| `lb_cluster_size` | 2 | 负载均衡器数量(至少为1) |
| `host_port` | 8080 | 暴露的主机起始端口(1024-65535之间) |
| `config_dir` | ./nginx-configs | 配置文件存储目录 |
| `source_dir` | (可选) | 自定义网页文件源目录 |

### 示例用法
```bash
# 最简调用,使用所有默认参数
./nginx_init.bash

# 自定义配置:5个后端节点,3个负载均衡器,从8000端口开始映射
./nginx_init.bash 5 3 8000 ./my-configs

# 使用自定义网页文件
./nginx_init.bash 3 2 8080 ./nginx-configs /path/to/my/web/files
```


## 3. 运行时交互

脚本运行时会提示用户输入以下信息:

1. **架构层级选择**
   ```
   请输入您要创建的nginx层级,2 代表2层,3 代表3层:
   请选择架构层级 (2/3):
   ```


2. **总线 Nginx 端口(仅在需要创建总线 Nginx 时出现)**
   ```
   总线nginx对外暴露的端口:
   ```


## 4. 架构选项说明

### 2层架构
- 包含后端节点和负载均衡器
- 请求流程:客户端 → 负载均衡器 → 后端节点
- 可通过修改 `Add_Nginx_Bus` 变量为 `true` 来添加总线 Nginx

### 3层架构
- 包含后端节点、负载均衡器和总线 Nginx
- 请求流程:客户端 → 总线 Nginx → 负载均衡器 → 后端节点

## 5. 输出信息

脚本执行完成后会显示:
- 集群状态概览
- 配置目录位置
- 各组件规模信息
- 访问地址
- 各节点的颜色标识

## 6. 注意事项

- 脚本会自动清理之前的同名容器和网络
- 需要 Docker 环境支持
- 确保指定的端口未被占用
- 如提供 `source_dir` 参数,需确保目录存在且包含有效网页文件


正文到此结束