1. 为什么需要负载均衡?
当你的网站用户从几百人增长到几万人时,单台服务器开始力不从心。我清楚地记得去年帮一家电商客户处理"双11"大促时的场景:凌晨流量暴增导致服务器CPU直接飙到100%,页面加载时间从1秒变成10秒,订单直接流失了15%。这就是典型的单点故障问题。
负载均衡就像交通指挥中心,把涌入的车辆(用户请求)合理分配到不同的道路(服务器)上。Nginx作为最常用的负载均衡解决方案之一,其事件驱动架构可以轻松处理数万并发连接。我在生产环境中实测过,单台Nginx服务器能稳定处理2万+的QPS(每秒查询率),而资源占用仅为Apache的一半。
2. 负载均衡核心原理
2.1 流量分发机制
Nginx的负载均衡本质上是一个智能的反向代理。当用户请求到达时,Nginx会根据预设策略从服务器池(upstream)中选择一个最合适的后端服务器,将请求转发过去。这个过程对用户完全透明,他们始终只看到Nginx的IP地址。
关键点:反向代理与正向代理的区别在于,正向代理代表客户端(如浏览器插件),反向代理代表服务端(如Nginx)。
2.2 四层 vs 七层负载均衡
根据OSI模型不同层级,负载均衡可分为:
- 四层(传输层):基于IP+端口进行转发(如LVS)
- 七层(应用层):能解析HTTP协议内容(如Nginx)
Nginx主要工作在七层,这意味着它可以:
- 根据URL路径路由请求(如/api/去A服务器,/static/去B服务器)
- 读取Cookie做会话保持
- 实现基于域名的虚拟主机
3. 实战环境搭建
3.1 服务器规划建议
根据我的运维经验,建议采用以下架构:
code复制 +-----------------+
| Nginx LB |
| (1核2G足够) |
+--------+--------+
|
+------------------+------------------+
| | |
+--------+--------+ +-------+-------+ +-------+-------+
| Web Server 1 | | Web Server 2 | | Web Server 3 |
| (2核4G起步) | | (2核4G起步) | | (2核4G起步) |
+-----------------+ +----------------+ +----------------+
3.2 Nginx安装细节
以Ubuntu 20.04为例,推荐使用官方源安装:
bash复制# 安装依赖
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
# 导入官方GPG密钥
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
# 设置稳定版源
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
# 安装
sudo apt update
sudo apt install nginx
避坑提示:千万不要用系统自带的旧版Nginx,很多新特性不支持。曾经有客户因为使用Ubuntu 18.04默认源里的Nginx 1.14,导致HTTP/2无法正常工作。
4. 核心配置详解
4.1 upstream模块精讲
这是负载均衡的核心配置区块,完整参数示例:
nginx复制upstream backend {
# 基础服务器定义
server 192.168.1.101:8080 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8080 weight=1;
server backup.example.com:8080 backup;
# 负载均衡算法
least_conn; # 最少连接算法
# 健康检查
keepalive 32;
keepalive_timeout 60s;
}
关键参数说明:
weight:权重值,weight=5的服务器会获得5倍于weight=1的流量max_fails:连续失败次数超过该值则标记为不可用fail_timeout:服务器被标记为不可用的持续时间backup:备用服务器,只有当所有主服务器不可用时才启用keepalive:到后端服务器的长连接池大小
4.2 代理配置优化
生产环境必备的proxy配置:
nginx复制location / {
proxy_pass http://backend;
# 超时控制
proxy_connect_timeout 2s;
proxy_read_timeout 5s;
proxy_send_timeout 3s;
# 头信息传递
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_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
# 错误处理
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
}
5. 高级调优策略
5.1 会话保持方案
对于需要登录的应用,必须保证同一用户的请求落到同一后端。推荐两种方案:
方案一:ip_hash(简单但不够精确)
nginx复制upstream backend {
ip_hash;
server 192.168.1.101;
server 192.168.1.102;
}
方案二:sticky cookie(更精准)
nginx复制upstream backend {
sticky cookie srv_id expires=1h domain=.example.com path=/;
server 192.168.1.101;
server 192.168.1.102;
}
5.2 动态权重调整
通过Nginx Plus或OpenResty可以实现运行时权重调整:
lua复制# 需要安装nginx-upsync-module
upstream backend {
upsync 127.0.0.1:8500/v1/kv/upstreams/backend upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;
upsync_dump_path /var/lib/nginx/backup.conf;
server 192.168.1.101:8080 weight=10;
server 192.168.1.102:8080 weight=10;
}
6. 监控与排错
6.1 状态监控配置
启用Nginx status模块:
nginx复制server {
listen 8080;
server_name localhost;
location /nginx_status {
stub_status;
access_log off;
allow 127.0.0.1;
deny all;
}
}
输出示例:
code复制Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106
6.2 关键指标解读
- Active connections:当前活跃连接数
- Waiting:保持连接状态的空闲连接数
- QPS计算:requests / (handled - accepts)
- 错误率:非200响应占比
6.3 日志分析技巧
推荐日志格式:
nginx复制log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'upstream_addr=$upstream_addr '
'request_time=$request_time upstream_response_time=$upstream_response_time';
用AWK分析慢请求:
bash复制awk '$NF>1 {print $1,$4,$7,$NF}' /var/log/nginx/access.log | sort -k4 -rn | head -20
7. 性能压测数据
使用wrk进行基准测试:
bash复制wrk -t12 -c400 -d30s http://lb.example.com
典型优化前后的对比(4台2核4G后端服务器):
| 配置项 | 优化前 (QPS) | 优化后 (QPS) |
|---|---|---|
| 默认配置 | 8,200 | - |
| 开启keepalive | - | 14,500 |
| 调优buffer | - | 18,300 |
| 启用gzip | - | 22,700 |
8. 常见故障处理
问题一:502 Bad Gateway
- 检查后端服务是否存活
- 查看Nginx error log中的连接超时记录
- 调整proxy_connect_timeout参数
问题二:负载不均
- 检查是否有服务器设置了不同的weight
- 确认是否误用了ip_hash导致某些IP过于集中
- 使用least_conn算法替代默认轮询
问题三:Nginx CPU飙高
- 通过
top -H -p nginx_pid查看具体线程 - 关闭access_log临时排除日志IO问题
- 检查是否受到CC攻击
9. 安全加固建议
- 限制连接频率:
nginx复制limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
location / {
limit_req zone=one burst=20;
}
}
- 隐藏Nginx版本号:
nginx复制server_tokens off;
- 禁用危险方法:
nginx复制if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 405;
}
在实际部署中,我通常会先用Ansible批量修改所有Nginx节点的安全配置,再通过灰度发布逐步验证。记住,负载均衡器本身就是关键基础设施,它的安全性直接影响整个系统的可靠性。