Nginx 负载均衡调度与高并发性能优化实践
流量调度与负载均衡配置
HTTP 层反向代理与调度
在 HTTP 协议层面,Nginx 通过 upstream 块来实现后端服务器池的管理与流量分发。
http {
upstream backend_pool {
# 启用基于客户端 IP 的哈希调度
# ip_hash;
# 定义后端节点及权重
server 10.0.0.11:80 weight=3;
# 标记该节点为下线状态,不参与调度
server 10.0.0.12:80 down;
# 设置失败阈值与超时时间
server 10.0.0.13:80 max_fails=3 fail_timeout=20s;
}
server {
listen 80;
server_name example.com;
location / {
# 将请求转发至定义的后端池
proxy_pass http://backend_pool;
}
}
}
核心调度算法
- 轮询 (Round Robin):默认策略,按顺序逐一分配请求。
- 权重 (Weight):结合轮询使用,权重值越高的节点接收的请求比例越大。
- IP 哈希 (ip_hash):基于客户端 IP 地址计算哈希值,确保同一 IP 的请求始终路由到同一后端节点,适用于需要保持会话的场景。
- 最少连接 (least_conn):优先将新请求分配给当前活动连接数最少的节点。
节点状态控制
down:将节点标记为不可用,停止向其分发流量。max_fails:在fail_timeout时间段内允许的最大失败请求数,超过此值则暂时剔除该节点。fail_timeout:节点达到最大失败次数后的冷却时间,期间不会接收新请求。
四层 TCP/UDP 流量代理
对于非 HTTP 协议(如数据库连接、SSH 等),需要启用 stream 模块。在编译 Nginx 时需添加 --with-stream 参数。
stream {
upstream tcp_backend {
server 10.0.0.21:3306;
server 10.0.0.22:3306 backup;
}
server {
listen 3306;
proxy_pass tcp_backend;
proxy_timeout 20s;
proxy_connect_timeout 5s;
}
}
http {
# HTTP 相关配置
}
状态监控与异常处理
HTTP 状态码与自定义错误页
了解常见的 HTTP 状态码有助于快速定位问题:
| 状态码 | 含义说明 |
|---|---|
| 200 | 请求成功 |
| 301 / 302 | 永久重定向 / 临时重定向 |
| 400 | 客户端请求语法错误 |
| 401 / 403 | 未授权 / 禁止访问(权限不足或 IP 被拒) |
| 404 | 请求的资源不存在 |
| 414 | 请求的 URI 过长 |
| 500 | 服务器内部错误 |
| 502 / 504 | 网关错误(后端无响应) / 网关超时 |
通过 error_page 指令可以优雅地处理异常状态,提升用户体验:
http {
# 允许 FastCGI 拦截错误
fastcgi_intercept_errors on;
server {
listen 80;
server_name app.example.com;
# 将 404 错误重定向到自定义页面
error_page 404 /custom_404.html;
# 统一处理 5xx 服务端错误
error_page 500 502 503 504 /custom_50x.html;
location = /custom_50x.html {
root /var/www/error_pages;
internal;
}
}
}
启用运行状态监控
使用 http_stub_status_module 模块可以暴露 Nginx 的实时连接数据。若已安装的 Nginx 缺少此模块,可通过重新编译并将新生成的二进制文件替换旧文件来热升级,无需清空现有配置。
# 编译时加入状态模块
./configure --with-http_stub_status_module --with-stream
make
# 备份并替换主程序(无需 make install)
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
cp objs/nginx /usr/local/nginx/sbin/
# 平滑重启
kill -HUP $(cat /usr/local/nginx/logs/nginx.pid)
在配置文件中暴露状态接口:
server {
listen 8080;
server_name localhost;
location /nginx_status {
stub_status;
# 建议限制访问 IP
allow 10.0.0.0/24;
deny all;
}
}
高并发与性能调优策略
进程与连接数优化
在进行压力测试(如使用 ab -c 200 -n 10000 http://target/)后,通常需要调整基础并发参数。
# 设置工作进程数,通常与 CPU 核心数保持一致或设置为 auto
worker_processes auto;
events {
# 使用 epoll 模型提升 Linux 下的并发处理能力
use epoll;
# 单个 worker 进程允许的最大并发连接数
worker_connections 4096;
# 允许一个 worker 同时打开多个文件
multi_accept on;
}
注意:调整 worker_connections 后,必须同步修改操作系统的文件描述符限制。编辑 /etc/security/limits.conf:
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535
解决 URI 过长导致的 414 错误
当客户端发送带有极长查询字符串的 GET 请求时,Nginx 默认会拒绝并返回 414 状态码。可以通过增大请求头缓冲区来解决:
http {
# 默认请求头缓冲区大小
client_header_buffer_size 16k;
# 针对超大请求头的缓冲区数量及单个大小
large_client_header_buffers 4 64k;
}
静态资源浏览器缓存
合理设置缓存头可以大幅减少重复请求,降低服务器带宽压力:
server {
listen 80;
server_name static.example.com;
# 针对多媒体及前端静态文件设置长效缓存
location ~* \.(css|js|jpg|jpeg|png|gif|ico|woff2)$ {
root /var/www/static;
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
}
带宽控制与限速
通过 limit_rate 指令可以限制向客户端传输响应的速度,防止大文件下载占满带宽:
http {
server {
listen 80;
server_name downloads.example.com;
# 全局默认限速 500KB/s
limit_rate 500k;
location /premium/ {
# 针对特定目录取消限速
limit_rate 0;
}
location /free/ {
# 针对免费资源严格限速 100KB/s
limit_rate 100k;
}
}
}
防盗链配置
利用 valid_referers 校验请求来源,防止外部站点恶意盗用本站图片或其他静态资源:
server {
listen 80;
server_name img.example.com;
location ~* \.(jpg|png|gif)$ {
root /var/www/images;
# 允许空 Referer、本站域名及指定搜索引擎访问
valid_referers none blocked server_names *.example.com baidu.com google.com;
if ($invalid_referer) {
# 盗链请求返回 403 或重定向到警告图片
return 403;
# rewrite ^/.*$ /anti_leech.jpg break;
}
}
}