Nginx反向代理配置实战:从负载均衡到健康检查的完整方案

Nginx反向代理服务器运维中最核心的基础设施之一。在高并发场景下,合理的反向代理配置直接决定了后端服务的稳定性和响应速度。本文以实际生产环境为例,覆盖负载均衡、健康检查、SSL终结、连接数控制等关键配置项。

反向代理基础配置与upstream定义

Nginx的upstream模块定义了后端服务器池,所有请求分发策略基于此配置。一个生产可用的upstream定义如下:

# /etc/nginx/conf.d/upstream.conf
upstream backend_api {
    server 10.0.1.11:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 10.0.1.12:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 10.0.1.13:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 10.0.1.20:8080 backup;
    keepalive 32;
    keepalive_timeout 60s;
}

参数说明:weight控制流量分配比例;max_fails指定在fail_timeout时间内允许的失败次数,超过后暂时移出负载均衡池;backup标记的服务器仅在所有主服务器不可用时才接收请求。

负载均衡算法选择与场景适配

Nginx默认使用加权轮询(weighted round-robin),但生产环境往往需要更精细的分发策略。

最少连接数策略适用于请求处理时间差异较大的场景:

upstream backend_api {
    least_conn;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
}

轮询算法可能导致某些服务器堆积大量慢请求,而least_conn能自动将请求分发到当前活跃连接数最少的服务器,实现负载均衡。

IP哈希策略适用于需要会话保持的场景:

upstream backend_api {
    ip_hash;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
}

ip_hash基于客户端IP的哈希,同一IP固定分发到同一服务器。但注意当后端服务器增减时,哈希环会重新计算,导致部分用户会话丢失。更好的做法是在应用层使用Redis等外部存储管理session。

主动健康检查配置

Nginx开源版仅支持被动健康检查,请求失败后才标记服务器不可用。主动健康检查需要nginx_upstream_check_module模块,编译安装后配置方式如下:

upstream backend_api {
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
    check interval=3000 rise=2 fall=3 timeout=2000 type=http;
    check_http_send "GET /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

server {
    location /upstream_status {
        check_status;
        access_log off;
        allow 10.0.0.0/8;
        deny all;
    }
}

参数含义:interval=3000每3秒检查一次;rise=2连续2次成功才标记为可用;fall=3连续3次失败才标记为不可用;type=http使用HTTP协议检查。后端服务需实现/health接口返回HTTP 200表示健康。

# Python Flask示例
@app.route('/health')
def health_check():
    try:
        db.session.execute('SELECT 1')
        return '', 200
    except Exception:
        return '', 503

SSL终结与HTTP/2配置

在反向代理层做SSL终结,后端服务使用纯HTTP通信,能减少后端CPU消耗并简化证书管理。

server {
    listen 443 ssl http2;
    server_name api.example.com;
    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
    add_header Strict-Transport-Security "max-age=31536000" always;
    
    location / {
        proxy_pass http://backend_api;
        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_set_header X-Forwarded-Proto $scheme;
    }
}

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

注意proxy_http_version设置为1.1并清空Connection头,这是启用upstream keepalive的必要条件。否则Nginx会为每个请求新建到后端的TCP连接,keepalive配置不生效。

连接数控制与限流配置

服务器安全加固中,连接数控制和请求限流是关键防线。Nginx提供了多层次的限流机制:

http {
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=100r/s;
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    
    server {
        location /api/ {
            limit_req zone=req_limit burst=50 nodelay;
            limit_conn conn_limit 20;
            limit_req_status 429;
            limit_conn_status 429;
            proxy_pass http://backend_api;
        }
    }
}

burst参数是限流的核心:rate=100r/s表示平均每秒100个请求,burst=50允许瞬时50个请求排队。nodelay选项使排队请求立即转发而非等待,适合对延迟敏感的API。不加nodelay时排队请求会按rate匀速转发。

性能调优关键参数

高可用集群部署中,以下参数需要根据服务器硬件和业务负载调整:

worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 16384;
    use epoll;
    multi_accept on;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    keepalive_requests 1000;
    gzip on;
    gzip_min_length 1024;
    gzip_types text/plain application/json application/javascript text/css;
    client_max_body_size 50m;
    client_body_buffer_size 128k;
    proxy_buffer_size 4k;
    proxy_buffers 8 4k;
    proxy_busy_buffers_size 8k;
}

worker_connections的设置需要结合系统文件描述符限制。假设worker_processes=8,worker_connections=16384,理论最大连接数为8乘以16384等于131072。需要确保系统的ulimit不低于此值。

故障排查常用命令

服务器故障排查时,以下Nginx命令和日志分析技巧常用:

nginx -t          # 测试配置语法
nginx -s reload   # 平滑重载配置

# 分析访问日志中请求最频繁的IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 分析响应时间最慢的请求
awk '($NF > 2){print $7, $NF, $1}' /var/log/nginx/access.log | sort -k2 -rn | head -20

# 统计各HTTP状态码占比
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

建议在nginx.conf中自定义日志格式,加入请求时间和upstream响应时间:

log_format main '$remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent" '
                 'rt=$request_time urt=$upstream_response_time '
                 'uct=$upstream_connect_time uht=$upstream_header_time';

其中$request_time是Nginx接收完整请求到发送完响应的总时间,$upstream_response_time是后端处理时间。两者的差值即为Nginx自身的开销。如果request_time远大于upstream_response_time,问题出在Nginx配置或网络层而非后端服务。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/nginx-fan-xiang-dai-li-pei-zhi-shi-zhan-cong-fu-zai-jun/

(0)
小编小编
上一篇 16小时前
下一篇 16小时前

相关推荐