Nginx 反向代理与负载均衡

Nginx 反向代理与负载均衡

ℹ️深入理解 Nginx 反向代理和负载均衡配置与实战应用

🎯 学习目标

  • 理解反向代理的原理和应用场景
  • 掌握 Nginx 负载均衡的多种策略
  • 学习高可用架构的配置方法
  • 实战:搭建生产级负载均衡系统

📋 反向代理详解

🔍 什么是反向代理?

反向代理(Reverse Proxy):代理服务器接收客户端请求,然后将请求转发给后端服务器,后端服务器处理完后将结果返回给代理服务器,代理服务器再返回给客户端。



graph LR
    A[客户端] --> B[Nginx反向代理]
    B --> C[后端服务器1]
    B --> D[后端服务器2]
    B --> E[后端服务器3]

    C --> B
    D --> B
    E --> B
    B --> A

🏗️ 反向代理的优势

优势 说明
负载均衡 分发请求到多台服务器,提高整体性能
安全性 隐藏后端服务器真实IP,增强安全性
缓存 缓存静态资源,减轻后端压力
SSL 终止 统一处理 HTTPS,简化后端配置
统一入口 多个服务通过同一个域名访问

🚀 反向代理基础配置

简单反向代理

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name api.example.com;

location / {
proxy_pass http://localhost:3000; # 后端服务地址
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;
}
}

常用代理头说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 传递原始主机头
proxy_set_header Host $host;

# 传递客户端真实IP
proxy_set_header X-Real-IP $remote_addr;

# 传递客户端IP链(包含所有代理IP)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# 传递原始协议(http/https)
proxy_set_header X-Forwarded-Proto $scheme;

# 传递原始请求URI
proxy_set_header X-Forwarded-Host $host:$server_port;

⚖️ 负载均衡详解

🔄 负载均衡策略

Nginx 支持多种负载均衡策略,每种策略适用于不同的场景:



graph TD
    A[Nginx负载均衡] --> B[轮询策略]
    A --> C[最少连接]
    A --> D[IP哈希]
    A --> E[权重分配]
    A --> F[热备模式]

    B --> B1[默认策略<br/>平均分配请求]
    C --> C1[连接数最少<br/>优先分配]
    D --> D1[基于IP计算<br/>会话保持]
    E --> E1[按性能权重<br/>分配请求]
    F --> F1[备用服务器<br/>故障时启用]

1. 轮询策略(默认)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}

server {
listen 80;
server_name www.example.com;

location / {
proxy_pass http://backend;
}
}

特点:按顺序逐一分配请求,平均分配负载。

2. 权重分配

1
2
3
4
5
upstream backend {
server 192.168.1.10:8080 weight=3; # 高性能服务器,权重为3
server 192.168.1.11:8080 weight=2; # 中等性能服务器
server 192.168.1.12:8080 weight=1; # 低性能服务器
}

特点:根据服务器性能设置权重,性能越强权重越高。

3. 最少连接

1
2
3
4
5
6
upstream backend {
least_conn; # 启用最少连接策略
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}

特点:优先将请求分配给当前连接数最少的服务器。

4. IP 哈希

1
2
3
4
5
6
upstream backend {
ip_hash; # 启用IP哈希策略
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}

特点:根据客户端IP计算哈希值,同一IP总是访问同一服务器,解决会话保持问题。

5. 热备模式

1
2
3
4
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080 backup; # 标记为备用服务器
}

特点:备用服务器只在主服务器故障时才接管请求。


🛠️ 高级负载均衡配置

健康检查

1
2
3
4
5
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 max_fails=3 fail_timeout=30s;
}

参数说明

  • max_fails=3:30秒内失败3次则标记为不可用
  • fail_timeout=30s:失败后30秒内不再分配请求

完整配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 定义后端服务器组
upstream backend_servers {
# 负载均衡策略
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;

# 保持连接
keepalive 32;
}

server {
listen 80;
server_name www.example.com;

# 日志配置
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

location / {
# 代理配置
proxy_pass http://backend_servers;

# 请求头设置
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;
proxy_busy_buffers_size 8k;
}

# 健康检查端点
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}

🔒 反向代理安全配置

隐藏后端服务器信息

1
2
3
4
5
6
# 隐藏后端服务器响应头
proxy_hide_header X-Powered-By;
proxy_hide_header Server;

# 设置自定义响应头
proxy_set_header Server "My-Server";

访问控制

1
2
3
4
5
6
7
8
9
10
11
12
13
# 限制IP访问
location /admin {
proxy_pass http://backend;
allow 192.168.1.0/24; # 允许内网访问
deny all; # 拒绝其他所有访问
}

# 基本认证
location /api {
proxy_pass http://backend;
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
}

📊 负载均衡监控

状态监控配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 编译时需要添加 nginx-module-sts 模块
# 或使用 nginx-module-vts 模块

server {
listen 80;
server_name status.example.com;

location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
}

监控指标说明

1
2
3
4
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106

指标含义

  • Active connections:当前活跃连接数
  • accepts:已接受的总连接数
  • handled:已处理的总连接数
  • requests:已处理的总请求数
  • Reading:正在读取请求头的连接数
  • Writing:正在读取请求体或处理请求的连接数
  • Waiting:空闲连接数

🎯 实战案例

案例1:微服务架构负载均衡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 用户服务
upstream user_service {
least_conn;
server user1.example.com:8001 weight=2;
server user2.example.com:8001 weight=1;
}

# 订单服务
upstream order_service {
ip_hash;
server order1.example.com:8002;
server order2.example.com:8002;
}

# 支付服务
upstream payment_service {
server payment1.example.com:8003 backup;
server payment2.example.com:8003;
}

server {
listen 80;
server_name api.example.com;

# 用户服务路由
location /api/users {
proxy_pass http://user_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# 订单服务路由
location /api/orders {
proxy_pass http://order_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# 支付服务路由
location /api/payment {
proxy_pass http://payment_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

案例2:静态+动态分离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 静态资源服务器
upstream static_servers {
server static1.example.com;
server static2.example.com;
}

# 动态应用服务器
upstream app_servers {
least_conn;
server app1.example.com:8080;
server app2.example.com:8080;
}

server {
listen 80;
server_name www.example.com;

# 静态资源代理
location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg|woff|woff2)$ {
proxy_pass http://static_servers;
expires 30d;
add_header Cache-Control "public, immutable";
}

# 动态请求代理
location / {
proxy_pass http://app_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

🛡️ 高可用架构

Keepalived + Nginx 高可用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 安装 keepalived
sudo apt install keepalived

# 配置文件 /etc/keepalived/keepalived.conf
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -20
}

vrrp_instance VI_1 {
state MASTER # 主服务器
interface eth0 # 网卡名称
virtual_router_id 51 # 虚拟路由ID
priority 100 # 优先级
advert_int 1

authentication {
auth_type PASS
auth_pass 1234
}

virtual_ipaddress {
192.168.1.100 # 虚拟IP
}

track_script {
check_nginx
}
}

📝 故障排查

常见问题及解决方案

问题 原因 解决方案
502 Bad Gateway 后端服务不可用 检查后端服务状态和配置
504 Gateway Timeout 后端响应超时 增加 proxy_read_timeout
无法连接后端 防火墙阻止 检查防火墙规则
会话丢失 负载均衡策略 使用 ip_hash 或会话共享

🔗 相关资源

学习资源


💡 实践建议

[success] 学习建议

  1. 从简单的反向代理开始练习
  2. 逐步尝试不同的负载均衡策略
  3. 在测试环境中模拟故障场景
  4. 学习监控和日志分析方法
  5. 了解高可用架构的配置

下一步:继续学习 03_Nginx性能优化与安全配置_最佳实践