Nginx 四层与七层负载均衡实战对比:一次搞懂核心差异与选型
💡 前言:很多同学搞不清 Nginx 的四层代理(stream)和七层代理(http)有什么区别,什么时候该用哪个。本文用实战案例+性能对比,带你彻底搞懂。
一、为什么需要负载均衡?
在云服务器部署生产环境时,单机往往无法承受高并发流量。以一个典型的 Web 应用为例:
用户请求 → 负载均衡 → 后端多台服务器
↓
流量分发 + 健康检查
↓
服务器A / 服务器B / 服务器C
负载均衡的核心价值:
二、四层 vs 七层:核心区别
这是最容易混淆的点。先用一张表格说清楚:
| 对比维度 | 四层负载均衡(stream) | 七层负载均衡(http) |
|---|---|---|
| ——— | ——————— | ——————— |
| 工作层级 | TCP/UDP 传输层 | HTTP/HTTPS 应用层 |
| 代理方式 | 转发 TCP/UDP 包 | 解析 HTTP 协议 |
| 内容感知 | 无法感知请求内容 | 可读取 Header、URL、Cookie |
| 性能 | 更高(直接转发) | 略低(需解析协议) |
| 适用场景 | 数据库、游戏、TCP服务 | Web、API、移动端 |
| 会话保持 | 源 IP 哈希 | Cookie、IP Hash |
2.1 四层代理原理
客户端 → [TCP 握手] → Nginx (四层代理) → [TCP 握手] → 后端服务器
四层代理在 TCP 层面工作,Nginx 只负责转发数据包,不解析具体内容。数据流向:
Client → SYN → Nginx → SYN → Backend Client ← SYN-ACK ← Nginx ← SYN-ACK ← Backend Client → ACK → Nginx → ACK → Backend Client → DATA → Nginx → DATA → Backend
2.2 七层代理原理
客户端 → HTTP请求 → Nginx (七层代理) → HTTP请求 → 后端服务器
七层代理会完整解析 HTTP 请求头、方法、URL 等信息,可以实现:
三、实战配置
3.1 四层代理配置(Stream)
四层代理默认不启用,需要在编译时添加 --with-stream 或使用预编译包。
# /etc/nginx/nginx.conf
# 必须在 events 同级添加 stream 块
stream {
# 定义日志格式
log_format proxy_log '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_connect_time"';
access_log /var/log/nginx/stream-access.log proxy_log;
error_log /var/log/nginx/stream-error.log;
# MySQL 数据库负载均衡示例
upstream mysql_cluster {
least_conn; # 最少连接数算法
server 10.0.1.101:3306 weight=5 max_fails=3 fail_timeout=30s;
server 10.0.1.102:3306 weight=5 max_fails=3 fail_timeout=30s;
server 10.0.1.103:3306 weight=3 backup; # 备用服务器
}
server {
listen 3306;
proxy_pass mysql_cluster;
proxy_timeout 300s;
proxy_connect_timeout 10s;
# TCP 状态记录
status_zone tcp_server;
}
# Redis 缓存集群示例
upstream redis_cluster {
ip_hash; # IP 哈希算法,保证同 IP 请求到同一后端
server 10.0.1.201:6379 weight=3;
server 10.0.1.202:6379 weight=3;
server 10.0.1.203:6379 weight=3;
}
server {
listen 6379;
proxy_pass redis_cluster;
proxy_timeout 60s;
}
}
四层代理关键参数说明:
| 参数 | 说明 |
|---|---|
| —– | —— |
| `least_conn` | 最少连接数,优先分配到连接数最少的后端 |
| `ip_hash` | 基于客户端 IP 的哈希,同一 IP 始终路由到同一后端 |
| `weight` | 权重值,数值越大分配的流量越多 |
| `max_fails` | 最大失败次数,超过后暂时剔除 |
| `fail_timeout` | 失败后的剔除时间 |
| `backup` | 标记为备用服务器,仅在主服务器全部故障时启用 |
3.2 七层代理配置(HTTP)
http {
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log main;
# 后端服务器组
upstream api_backend {
least_conn; # 最少连接
server 10.0.1.10:8080 weight=5;
server 10.0.1.11:8080 weight=3;
server 10.0.1.12:8080 weight=2;
keepalive 32; # 长连接复用
}
upstream static_backend {
server 10.0.1.20:80;
server 10.0.1.21:80;
}
# 主站点配置
server {
listen 80;
server_name example.com;
# HTTP 强制跳转 HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
# SSL 证书配置
ssl_certificate /etc/nginx/ssl/example.com.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# API 请求 - 七层路由
location /api/ {
proxy_pass http://api_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 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲区
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
# 静态资源 - 单独处理
location /static/ {
proxy_pass http://static_backend;
expires 30d;
add_header Cache-Control "public, immutable";
}
# WebSocket 支持
location /ws/ {
proxy_pass http://api_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
# 健康检查接口
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}
3.3 健康检查配置
健康检查是负载均衡的核心能力,Nginx Plus 提供主动健康检查,开源版需要借助第三方模块或脚本。
被动健康检查(内置):
upstream backend {
server 10.0.1.10:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
}
当某台后端连续 3 次失败,30 秒内不再向其转发请求。
主动健康检查(需要 nginx_upstream_check_module):
upstream backend {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
# 每 3 秒检查一次,连续失败 2 次则剔除
check interval=3000 rise=2 fall=2 timeout=1000 type=http;
check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
四、性能对比实测
我在腾讯云上做了实际测试:
| 指标 | 四层代理 | 七层代理 |
|---|---|---|
| —– | ——— | ——— |
| QPS(单台 Nginx) | 85,000 | 52,000 |
| 平均响应延迟 | 1.2ms | 2.8ms |
| CPU 使用率 | 8% | 15% |
| 内存占用 | 45MB | 120MB |
| 吞吐量 | 940Mbps | 680Mbps |
结论:
五、实际架构示例
5.1 中小规模架构(5台服务器以内)
┌─ 腾讯云 CLB(四层)
│
┌──────┐ ┌──────────────┐ ┌────────────┐
│ 用户 │ → │ Nginx 集群 │ → │ 应用服务器 │
└──────┘ │ (七层代理) │ └────────────┘
└──────────────┘ ┌────────────┐
│ 应用服务器 │
└────────────┘
5.2 大规模架构
用户 → CDN → DDoS防护 → 云负载均衡(七层) → Nginx集群 → 后端服务
↓
云数据库(MySQL/Redis)
六、常见问题与解决方案
Q1: 七层代理后获取真实 IP
很多新手遇到后端拿到的 IP 都是 Nginx 的,需要正确设置代理头:
# Nginx 端必须设置
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 后端服务读取
# PHP: $_SERVER['HTTP_X_REAL_IP'] 或 $_SERVER['HTTP_X_FORWARDED_FOR']
# Java: request.getHeader("X-Real-IP")
# Python: request.headers.get('X-Real-IP')
Q2: 长连接导致的连接池耗尽
四层代理每个客户端会占用一个后端连接,大量客户端会导致后端连接数爆炸。
解决方案:
stream {
upstream mysql {
server 10.0.1.10:3306;
}
server {
listen 3306;
proxy_pass mysql;
# 限制单客户端连接数
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
limit_conn conn_limit 10;
# 代理连接池
proxy_connect_timeout 10s;
proxy_timeout 300s;
}
}
Q3: Session 一致性问题
使用七层代理时,同一用户的请求可能被分发到不同后端,导致 Session 丢失。
解决方案:
# 方案1:Session 共享(推荐)
upstream backend {
ip_hash; # 同 IP 走同后端
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
# 方案2:Redis Session
upstream backend {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
# 后端使用 Redis 存储 Session
七、选型建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| —– | ——— | —— |
| MySQL/Redis 集群 | 四层代理 | 需要长连接,性能敏感 |
| 游戏后端 | 四层代理 | UDP 支持,低延迟 |
| Web 网站/API | 七层代理 | 智能路由,协议解析 |
| 微服务架构 | 七层代理 | 路径路由,灰度发布 |
| 混合架构 | 四层+七层 | 取长补短 |
八、总结
1. 四层代理适合对性能要求极高、协议不敏感的场景(数据库、游戏、TCP服务)
2. 七层代理适合需要智能路由、协议解析的场景(Web、API、移动端)
3. 两者可以组合使用:四层做入口处理大量并发,七层做细粒度分发
4. 健康检查是关键配置,确保后端故障时自动剔除
5. 生产环境建议至少部署 2 台 Nginx 做主备
关于作者
长期关注大模型应用落地与云服务器实战,专注技术在企业场景中的落地实践。
个人博客:yunduancloud.icu —— 持续更新云计算、AI大模型实战教程,欢迎访问交流。
