Nginx反向代理配置与负载均衡

本文详解Nginx反向代理和负载均衡的配置方法,适用于WordPress多服务器部署。

基础反向代理配置

单后端反向代理

# /etc/nginx/sites-available/reverse-proxy
server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;  # 后端应用
        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_set_header X-Forwarded-Proto $scheme;
    }
}

WordPress反向代理配置

# WordPress在后端(不同端口或服务器)
upstream wordpress_backend {
    server 127.0.0.1:9000;  # PHP-FPM
    server 127.0.0.1:9001 backup;  # 备份
}

server {
    listen 80;
    server_name example.com;

    root /var/www/html;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        proxy_pass http://wordpress_backend;
        # 或者直接用fastcgi_pass
        # fastcgi_pass wordpress_backend;
    }
}

负载均衡配置

定义upstream(后端服务器池)

upstream wordpress_cluster {
    # 负载均衡算法(默认round-robin)
    # least_conn;      # 最少连接数
    # ip_hash;          # 按IP哈希(会话保持)
    # hash $request_uri consistent;  # 一致性哈希

    server 192.168.1.10:80 weight=5;   # 权重5
    server 192.168.1.11:80 weight=3;   # 权重3
    server 192.168.1.12:80 weight=2;   # 权重2
    server 192.168.1.13:80 backup;     # 备份服务器
    server 192.168.1.14:80 down;      # 标记下线
}

在server块中使用upstream

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://wordpress_cluster;

        # 传递真实客户端IP
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;

        # 超时设置
        proxy_connect_timeout 5s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # 缓冲设置
        proxy_buffering on;
        proxy_buffer_size 16k;
        proxy_buffers 8 16k;
    }
}

健康检查

被动健康检查(Nginx Plus/商业版)

# Nginx Plus 或 开源版 + nginx_upstream_check_module
upstream wordpress_cluster {
    server 192.168.1.10:80;
    server 192.168.1.11:80;

    # 健康检查(需要第三方模块)
    check interval=3000 rise=2 fall=3 timeout=1000 type=http;
    check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

主动健康检查(开源版方案)

# 使用max_fails + fail_timeout 实现被动健康检查
upstream wordpress_cluster {
    # max_fails: 失败次数阈值
    # fail_timeout: 失败后冷却时间
    server 192.168.1.10:80 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:80 max_fails=3 fail_timeout=30s;
}

# 配合健康检查端点
location /nginx_status {
    stub_status on;
    access_log off;
    allow 127.0.0.1;
    deny all;
}

使用外部健康检查脚本

#!/bin/bash
# /usr/local/bin/check_wordpress.sh

for server in 192.168.1.10 192.168.1.11; do
    # 检查WordPress登录页是否正常
    status=$(curl -s -o /dev/null -w "%{http_code}" http://$server/wp-login.php)

    if [ "$status" != "200" ]; then
        echo "$(date): $server is DOWN (HTTP $status)" >> /var/log/nginx/health_check.log
        # 自动从upstream移除(通过修改配置文件)
        # 实际生产环境建议使用Consul + Nginx Plus动态更新
    else
        echo "$(date): $server is OK" >> /var/log/nginx/health_check.log
    fi
done
# 添加到crontab(每分钟检查)
* * * * * /usr/local/bin/check_wordpress.sh

会话保持(Session Persistence)

upstream wordpress_cluster {
    # 使用sticky cookie(需要Nginx Plus或第三方模块)
    sticky cookie srv_id expires=1h domain=.example.com path=/;

    server 192.168.1.10:80;
    server 192.168.1.11:80;
}

基于IP哈希的会话保持

upstream wordpress_cluster {
    ip_hash;  # 同一IP总是转发到同一后端

    server 192.168.1.10:80;
    server 192.168.1.11:80;
}

WordPress会话共享(推荐)

// wp-config.php 配置Redis会话共享
define('WP_REDIS_HOST', '127.0.0.1');
define('WP_REDIS_PORT', 6379);

// 使用Redis存储会话(所有后端共享登录状态)
require_once 'wp-content/plugins/redis-cache/redis-cache.php';

缓存配置

代理缓存

# 定义缓存区
proxy_cache_path /var/cache/nginx/wordpress levels=1:2 keys_zone=wp_cache:10m max_size=1g inactive=60m use_temp_path=off;

server {
    location / {
        proxy_cache wp_cache;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        proxy_cache_valid 200 302 60m;
        proxy_cache_valid 404      1m;

        # 添加缓存状态头(调试用)
        add_header X-Cache-Status $upstream_cache_status;

        proxy_pass http://wordpress_cluster;
    }

    # 跳过缓存的条件
    proxy_cache_bypass $cookie_user_logged_in;
    proxy_no_cache       $cookie_user_logged_in;
}

静态资源缓存

location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg)$ {
    proxy_cache wp_cache;
    proxy_cache_valid 200 30d;
    expires 30d;
    add_header Cache-Control "public, immutable";

    proxy_pass http://wordpress_cluster;
}

SSL终止(SSL Termination)

Nginx处理SSL,后端用HTTP

upstream wordpress_backend {
    server 192.168.1.10:80;
    server 192.168.1.11:80;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    ssl_protocols       TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://wordpress_backend;
        proxy_set_header X-Forwarded-Proto https;
    }
}

日志配置

记录真实客户端IP

# 在http块中
log_format proxy_log '$remote_addr - $remote_user [$time_local] '
                     '"$request" $status $body_bytes_sent '
                     '"$http_referer" "$http_user_agent" '
                     'proxy: $upstream_addr '
                     'request_time: $request_time '
                     'upstream_time: $upstream_response_time';

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

性能优化

连接池复用

upstream wordpress_cluster {
    server 192.168.1.10:80;
    server 192.168.1.11:80;

    keepalive 32;  # 保持32个空闲连接
}

server {
    location / {
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_pass http://wordpress_cluster;
    }
}

常见问题

问题 原因 解决方案
后端获取不到真实IP 未设置X-Forwarded-For 添加proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
会话丢失 无会话保持 使用ip_hash或Redis共享会话
后端服务器雪崩 无熔断机制 配置max_fails + fail_timeout
缓存不生效 缓存key冲突 检查proxy_cache_key配置

完整示例配置

# WordPress负载均衡完整配置
upstream wordpress {
    least_conn;
    server 192.168.1.10:80 weight=5 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:80 weight=3 max_fails=3 fail_timeout=30s;
    server 192.168.1.12:80 backup;
}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=wp:10m max_size=1g inactive=60m;

server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    root /var/www/html;
    index index.php;

    location / {
        proxy_pass http://wordpress;
        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 wp;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        proxy_cache_valid 200 60m;
        add_header X-Cache-Status $upstream_cache_status;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        include fastcgi.conf;
    }
}

通过Nginx反向代理和负载均衡,可以将WordPress的并发处理能力扩展。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。