Nginx负载均衡算法选择
Nginx的upstream模块支持多种负载均衡算法,不同算法适用不同场景。round-robin(轮询)是默认策略,请求依次分发到各后端服务器,适合后端服务器配置相近的场景。least_conn将请求分发到当前活跃连接数最少的服务器,适合请求处理时间差异较大的场景。ip_hash基于客户端IP做哈希,同一IP始终路由到同一后端,适合需要会话保持的场景。
upstream配置示例:
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;
}
weight参数控制权重分配,权重越高分到的请求越多。max_fails和fail_timeout组合实现被动健康检查:在fail_timeout时间内失败max_fails次,该服务器在fail_timeout时间内被标记为不可用。backup标记的服务器仅在所有主服务器不可用时启用。keepalive维持到后端的长连接池,减少TCP握手开销。
主动健康检查方案
Nginx开源版不内置主动健康检查,仅支持被动检查(通过max_fails/fail_timeout)。两种实现主动健康检查的方案:
方案一:nginx_upstream_check_module第三方模块
该模块由淘宝开源,支持主动TCP/HTTP健康检查,需要编译安装:
# 下载模块源码
git clone https://github.com/yaoweibin/nginx_upstream_check_module.git
# 给Nginx源码打补丁
cd nginx-1.24.0
patch -p1 < ../nginx_upstream_check_module/check_1.20.1+.patch
# 编译安装
./configure --add-module=../nginx_upstream_check_module \
--with-http_ssl_module \
--with-http_v2_module
make && make install
配置示例:
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
check interval=3000 rise=2 fall=3 timeout=2000 type=http;
check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
check_shm_size 1m;
}
server {
location /status {
check_status;
access_log off;
allow 192.168.1.0/24;
deny all;
}
}
check指令每3秒(interval=3000)向后端发送HTTP健康检查请求,连续2次(rise=2)成功标记为可用,连续3次(fall=3)失败标记为不可用。check_http_send定义检查请求内容,通常请求/health端点。check_status提供web界面查看各后端健康状态。
方案二:Lua脚本配合ngx.timer实现
使用OpenResty内置的Lua引擎编写定时健康检查:
local hc = require "resty.healthcheck"
local checker = hc.new({
name = "backend",
checks = {
active = {
interval = 3,
timeout = 2,
path = "/health",
healthy = { http_statuses = { 200, 302 }, successes = 2, interval = 3 },
unhealthy = { http_statuses = { 500, 502, 503 }, failures = 3, interval = 3 }
}
}
})
checker:add_target("192.168.1.10", 8080)
checker:add_target("192.168.1.11", 8080)
-- 在balancer阶段使用健康检查结果
local balancer = require "ngx.balancer"
local host, port = checker:get_target()
balancer.set_current_peer(host, port)
HTTPS配置与SSL优化
反向代理场景下,Nginx处理SSL卸载,后端走HTTP:
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_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
location / {
proxy_pass http://backend;
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_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_next_upstream error timeout http_502 http_503 http_504;
proxy_next_upstream_tries 2;
}
}
proxy_next_upstream配置当后端返回502/503/504或超时时,自动重试下一个后端服务器。proxy_next_upstream_tries限制重试次数,避免请求被多次转发增加延迟。
SSL优化要点:仅启用TLS 1.2和1.3,禁用旧协议;使用ECDHE密钥交换实现前向保密;ssl_session_cache共享SSL会话缓存,减少TLS握手;TLS 1.3默认启用0-RTT,首次连接也能复用会话。
限流与熔断配置
Nginx通过limit_req模块实现请求限流:
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;
server {
location /api/ {
limit_req zone=api_limit burst=200 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
location /api/upload {
limit_conn conn_limit 10;
proxy_pass http://backend;
}
}
rate=100r/s表示每秒允许100个请求。burst=200设置突发请求队列上限200,nodelay表示突发请求立即处理不排队等待。limit_req_zone用$binary_remote_addr做key,以二进制IP地址标识客户端,比文本IP更省内存。
limit_conn控制每个IP的并发连接数,防止单个客户端耗尽连接池。limit_req_status设置拒绝请求时返回429状态码,符合HTTP语义。
日志格式与访问控制
自定义日志格式记录代理转发信息:
log_format upstream_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'urt="$upstream_response_time" uht="$upstream_header_time" '
'upstream=$upstream_addr status=$upstream_status';
access_log /var/log/nginx/access.log upstream_log;
upstream_connect_time记录与后端建立连接耗时,upstream_response_time记录后端响应耗时。这些指标对定位后端性能瓶颈至关重要。当request_time远大于upstream_response_time时,瓶颈在Nginx自身;当upstream_response_time过大时,需检查后端服务性能。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/nginx-fan-xiang-dai-li-pei-zhi-fu-zai-jun-heng-ce-lyue-yu/