Nginx负载均衡核心配置解析
Nginx作为反向代理服务器,其负载均衡功能通过upstream模块实现。在高并发场景下,默认的轮询(Round Robin)策略难以满足业务需求,需要根据实际情况选择合适的调度算法和调优参数。一台典型的四层负载均衡节点可承载10万级并发连接,但实际吞吐量取决于socket分配、内核参数和Nginx配置的协同优化。
upstream调度策略对比与选型
Nginx原生支持五种调度策略:轮询(默认)、权重轮询、ip_hash、least_conn和random。每种策略适用于不同的业务场景:
- 权重轮询:后端服务器配置weight参数,按比例分发请求。适用于服务器硬件配置不均的集群。
- ip_hash:根据客户端IP哈希值固定分配到同一后端,解决Session保持问题。但会导致负载分布不均。
- least_conn:优先将请求分配给当前活动连接数最少的服务器,适合请求处理时间差异较大的场景。
- random:随机选择后端服务器,在服务器配置均匀时性能优于轮询。
upstream backend {
least_conn;
server 192.168.1.10:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=2 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 weight=1 max_fails=3 fail_timeout=30s backup;
keepalive 32;
keepalive_timeout 60s;
}
max_fails和fail_timeout组合实现健康检查:30秒内失败3次的服务器将被临时摘除。backup参数标记备份服务器,仅当所有主服务器不可用时才启用。keepalive 32开启到后端的长连接池,避免频繁TCP握手,减少RTT开销。
工作进程与连接数调优
Nginx性能调优的第一步是合理配置worker_processes和worker_connections。worker_processes建议设为auto,Nginx会自动匹配CPU核心数。每个worker进程的最大连接数由worker_connections决定,该值需要根据系统fd(文件描述符)限制来设置。
# nginx.conf 主配置
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 16384;
use epoll; # Linux下使用epoll事件模型
multi_accept on; # 一次接收所有新连接
accept_mutex off; # 多worker时关闭互斥锁减少竞争
}
worker_connections设为16384时,理论最大并发连接数为 worker_processes × worker_connections。8核服务器理论上可支撑约13万并发连接。worker_rlimit_nofile需要大于worker_connections,建议设为65535。accept_mutex在高并发场景下建议关闭,避免worker进程间的锁竞争。
Linux内核网络参数优化
Nginx高并发依赖Linux内核网络栈的支持。以下参数需要写入/etc/sysctl.conf并执行sysctl -p生效:
# 文件描述符
fs.file-max = 1048576
# TCP连接相关
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_max_tw_buckets = 1048576
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# 全局连接队列
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
# TCP Keepalive
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
# TCP缓冲区
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
tcp_max_syn_backlog控制SYN队列长度,SYN Flood攻击或高并发握手场景下需要调大。somaxconn控制accept队列长度,必须大于Nginx的backlog配置。tcp_tw_reuse=1允许复用TIME_WAIT状态的连接,在高并发短连接场景下能有效减少端口耗尽问题。
反向代理缓冲与超时配置
Nginx作为反向代理时,缓冲区配置直接影响响应速度和内存占用。proxy_buffering开启时,Nginx会将后端响应缓存在内存或临时文件中,一次性发送给客户端,减少后端等待时间。
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 超时配置
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲区配置
proxy_buffering on;
proxy_buffer_size 16k;
proxy_buffers 8 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 128k;
# 透明传递客户端信息
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;
}
}
proxy_buffer_size设为16k处理响应头,proxy_buffers 8 32k分配8个32k缓冲区存储响应体。proxy_busy_buffers_size控制忙状态缓冲区大小,应小于proxy_buffers总大小。proxy_connect_timeout设为5秒快速感知后端不可用,proxy_read_timeout设为60秒覆盖慢请求场景。
健康检查与故障转移
Nginx开源版不提供主动健康检查功能,max_fails+fail_timeout实现的是被动健康检查——通过请求失败计数判断服务器状态。Nginx Plus或第三方模块nginx_upstream_check_module提供主动健康检查。
在没有主动健康检查的情况下,可以通过定时脚本探测后端状态,结合Nginx的API动态修改upstream配置:
import requests
import subprocess
import time
BACKENDS = ["192.168.1.10:8080", "192.168.1.11:8080", "192.168.1.12:8080"]
HEALTH_URL = "http://{}/health"
def check_backend(backend):
try:
resp = requests.get(HEALTH_URL.format(backend), timeout=3)
return resp.status_code == 200
except:
return False
def update_nginx_state(alive_backends):
alive = " ".join(alive_backends)
cmd = f'nginx -s reload'
# 通过配置模板动态生成upstream配置并reload
# 实际生产环境建议用consul-template或confd
pass
while True:
alive = [b for b in BACKENDS if check_backend(b)]
if len(alive) == 0:
print("所有后端不可用,触发告警")
else:
update_nginx_state(alive)
time.sleep(10)
连接复用与Keepalive优化
Nginx到后端服务器的连接复用能显著降低延迟。keepalive指令设定到每个上游服务器的空闲长连接最大数量。配合proxy_http_version 1.1和proxy_set_header Connection “”使用:
upstream backend {
server 192.168.1.10:8080;
keepalive 64;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
keepalive值建议设为worker_connections的1/4到1/2。64个空闲连接在中等负载下能覆盖大部分连接复用需求。proxy_set_header Connection “”清除客户端传来的Connection头,防止HTTP/1.0的close行为影响长连接。
日志与监控指标采集
Nginx的access log和error log是排查问题的重要依据。高负载环境下,日志写入会成为性能瓶颈,建议通过syslog将日志发送到外部日志服务器,或使用access_log off关闭非必要日志。
# 自定义日志格式,记录关键性能指标
log_format perf '$remote_addr - $request_time $upstream_response_time '
'$upstream_addr $status $body_bytes_sent "$request"';
access_log /var/log/nginx/access.log perf buffer=64k flush=5s;
error_log /var/log/nginx/error.log warn;
$request_time记录从接收第一个字节到发送完最后一个字节的总时间,$upstream_response_time记录后端处理时间。两者差值即为Nginx自身处理开销。buffer=64k设置日志缓冲区,flush=5s定时刷盘,减少磁盘IO。结合Prometheus的nginx_exporter可实现实时监控告警。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/nginx-gao-bing-fa-fu-zai-jun-heng-pei-zhi-shi-zhan-upstream/