Nginx代理服务从基础到架构实战

1. 概述

1.1 代理服务的重要性

代理服务在互联网架构中扮演着关键角色,就像现实生活中的代理租房、代理收货一样,在互联网请求中,客户端往往无法直接向服务端发起请求,这时就需要代理服务来实现客户端和服务端的通信。

Nginx作为代理服务可以实现多种协议的代理,主要包括:

  • HTTP/HTTPS代理:Web应用代理
  • TCP/UDP代理:四层负载均衡
  • WebSocket代理:实时通信代理

1.2 代理类型

1.2.1 正向代理

正向代理(Forward Proxy)

  • 代理对象:客户端
  • 作用:代理客户端访问服务端
  • 场景:内部上网、突破访问限制、隐藏客户端IP

架构图

1
客户端 <--> 正向代理 --> 服务端

特点

  • 客户端知道代理的存在
  • 服务端不知道真实的客户端
  • 代理代表客户端访问服务端

1.2.2 反向代理

反向代理(Reverse Proxy)

  • 代理对象:服务端
  • 作用:代理服务端接收客户端请求
  • 场景:负载均衡、高可用、SSL终端、缓存

架构图

1
客户端 --> 反向代理 <--> 服务端

特点

  • 客户端不知道真实的服务端
  • 服务端知道代理的存在
  • 代理代表服务端接收请求

1.3 代理区别总结

特性 正向代理 反向代理
代理对象 客户端 服务端
客户端感知 知道代理 不知道真实服务端
服务端感知 不知道真实客户端 知道代理
主要用途 突破限制、隐藏IP 负载均衡、高可用
典型场景 企业内网代理 Web服务器集群

1.4 本文内容结构

本文将从以下几个方面全面解析Nginx代理服务:

  1. Nginx代理服务概述:代理配置语法、正向代理、反向代理
  2. Nginx负载均衡:配置场景、状态配置、调度策略、TCP配置
  3. Nginx动静分离:应用案例、手机电脑应用案例

2. Nginx代理服务概述

2.1 Nginx代理配置语法

2.1.1 proxy_pass指令

基本语法

1
2
3
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except

URL格式

  • http://localhost:8000/uri/
  • http://192.168.56.11:8000/uri/
  • http://unix:/tmp/backend.socket:/uri/

配置示例

1
2
3
4
5
6
7
location / {
proxy_pass http://192.168.1.100:8080;
}

location /api/ {
proxy_pass http://192.168.1.100:8080/api/;
}

注意事项

  • URL末尾带/:会替换location匹配的路径
  • URL末尾不带/:会追加location匹配的路径

2.1.2 proxy_buffering缓冲区

基本语法

1
2
3
Syntax: proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location

作用

  • 尽可能收集所有头请求
  • 减少与后端服务器的连接次数
  • 提高代理性能

相关配置

1
2
3
4
5
6
7
8
9
10
11
# 缓冲区大小
proxy_buffer_size 4k;

# 缓冲区数量和大小
proxy_buffers 8 4k;

# 忙碌缓冲区大小
proxy_busy_buffers_size 8k;

# 临时文件大小
proxy_max_temp_file_size 256k;

完整配置示例

1
2
3
4
5
6
7
8
9
10
location / {
proxy_pass http://backend;

# 缓冲区配置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 256k;
}

2.1.3 proxy_redirect重定向

基本语法

1
2
3
4
5
Syntax: proxy_redirect default;
proxy_redirect off;
proxy_redirect redirect replacement;
Default: proxy_redirect default;
Context: http, server, location

作用

  • 修改后端服务器返回的重定向响应头
  • 将后端服务器的重定向地址转换为代理服务器的地址

配置示例

1
2
3
4
5
6
7
8
# 默认处理
proxy_redirect default;

# 禁用重定向处理
proxy_redirect off;

# 自定义重定向
proxy_redirect http://backend.example.com/ http://www.example.com/;

2.1.4 proxy_set_header头信息

基本语法

1
2
3
4
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location

常用配置

1
2
3
4
5
6
7
8
9
location / {
proxy_pass http://backend;

# 设置请求头
proxy_set_header Host $http_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
# 隐藏响应头
proxy_hide_header X-Powered-By;

# 设置请求体
proxy_set_body $request_body;

2.1.5 代理超时配置

连接超时

1
2
3
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location

读取超时

1
2
3
Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location

发送超时

1
2
3
Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location

配置示例

1
2
3
4
5
6
7
8
location / {
proxy_pass http://backend;

# 超时配置
proxy_connect_timeout 30s; # 连接超时
proxy_read_timeout 60s; # 读取超时
proxy_send_timeout 60s; # 发送超时
}

2.1.6 代理通用配置模板

创建proxy_params文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# /etc/nginx/proxy_params
proxy_redirect default;
proxy_set_header Host $http_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 30;
proxy_send_timeout 60;
proxy_read_timeout 60;

proxy_buffer_size 32k;
proxy_buffering on;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 256k;

使用proxy_params

1
2
3
4
location / {
proxy_pass http://127.0.0.1:8080;
include proxy_params;
}

2.2 Nginx正向代理示例

2.2.1 正向代理场景

应用场景

  • 企业内网代理:内部员工通过代理访问外网
  • 突破访问限制:访问被限制的资源
  • 隐藏客户端IP:保护客户端隐私

2.2.2 正向代理配置

基础配置

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
listen 80;

# DNS解析器
resolver 8.8.8.8 8.8.4.4;

location / {
proxy_pass http://$http_host$request_uri;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

完整配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# /etc/nginx/conf.d/forward_proxy.conf
server {
listen 80;

# DNS解析器(必须配置)
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

location / {
# 正向代理核心配置
proxy_pass http://$http_host$request_uri;

# 设置请求头
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# 超时配置
proxy_connect_timeout 30s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}

2.2.3 正向代理实战案例

场景:配置访问限制,仅允许同网段访问图片资源,通过正向代理突破限制。

1. 配置访问限制

1
2
3
4
5
6
7
8
9
10
11
12
13
# /etc/nginx/conf.d/access.conf
server {
listen 80;
server_name 192.168.69.113;

location ~ .*\.(jpg|gif|png)$ {
# 仅允许同网段访问
allow 192.168.69.0/24;
deny all;

root /soft/code/images;
}
}

2. 配置正向代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# /etc/nginx/conf.d/forward_proxy.conf
server {
listen 80;
server_name proxy.example.com;

# DNS解析器
resolver 8.8.8.8 8.8.4.4;

location / {
proxy_pass http://$http_host$request_uri;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

3. 客户端配置

使用浏览器插件(如SwitchySharp)配置代理

  • 代理类型:HTTP
  • 代理服务器:proxy.example.com
  • 代理端口:80

4. 验证效果

  • 未连接代理:访问被限制,返回403
  • 连接代理后:可以正常访问,突破限制

2.3 Nginx反向代理示例

2.3.1 反向代理场景

应用场景

  • 负载均衡:将请求分发到多个后端服务器
  • 高可用:后端服务器故障时自动切换
  • SSL终端:在代理层处理SSL/TLS
  • 缓存加速:缓存静态资源

2.3.2 反向代理配置

基础配置

1
2
3
4
5
6
7
8
9
10
11
# /etc/nginx/conf.d/reverse_proxy.conf
server {
listen 80;
server_name nginx.bjstack.com;
index index.html;

location / {
proxy_pass http://192.168.56.100;
include proxy_params;
}
}

完整配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 后端服务器
upstream backend {
server 192.168.1.100:8080;
server 192.168.1.101:8080;
}

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

location / {
proxy_pass http://backend;

# 包含通用代理配置
include proxy_params;

# 额外配置
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
}
}

2.3.3 反向代理实战案例

场景:配置Nginx反向代理,将请求转发到后端Web服务器。

1. 后端Web服务器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# /etc/nginx/conf.d/web_server.conf
server {
listen 80;
server_name nginx.bjstack.com;
root /soft/code;
index index.html;

location / {
root /soft/code;
index index.html;
}

location ~ .*\.(png|jpg|gif)$ {
gzip on;
root /soft/code/images;
}
}

2. 反向代理服务器配置

1
2
3
4
5
6
7
8
9
10
11
# /etc/nginx/conf.d/reverse_proxy.conf
server {
listen 80;
server_name nginx.bjstack.com;
index index.html;

location / {
proxy_pass http://192.168.56.100;
include proxy_params;
}
}

3. 验证效果

  • 客户端访问nginx.bjstack.com
  • 请求被转发到后端服务器192.168.56.100
  • 返回后端服务器的响应

3. Nginx负载均衡

3.1 负载均衡概述

3.1.1 负载均衡的作用

负载均衡的价值

  • 提升吞吐率:分散请求到多个服务器
  • 提升请求性能:减少单服务器压力
  • 提高容灾能力:单点故障不影响服务

3.1.2 负载均衡分类

按范围划分

  • GSLB(全局负载均衡):跨地域、跨数据中心的负载均衡
  • SLB(服务器负载均衡):同一数据中心的负载均衡

Nginx是典型的SLB

按层级划分

  • 四层负载均衡(L4):基于IP和端口(TCP/UDP)
  • 七层负载均衡(L7):基于HTTP协议

Nginx是典型的七层SLB

3.2 Nginx负载均衡配置场景

3.2.1 upstream模块

基本语法

1
2
3
Syntax: upstream name { ... }
Default: -
Context: http

配置示例

1
2
3
4
5
6
7
8
9
10
11
12
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
}

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

3.2.2 负载均衡实战案例

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
# 创建三个不同的目录和HTML文件
mkdir -p /soft/{code1,code2,code3}

# Code1服务器
cat > /soft/code1/index.html <<EOF
<html>
<title>Code1</title>
<body bgcolor="red">
<h1>Code1-8081</h1>
</body>
</html>
EOF

# Code2服务器
cat > /soft/code2/index.html <<EOF
<html>
<title>Code2</title>
<body bgcolor="blue">
<h1>Code2-8082</h1>
</body>
</html>
EOF

# Code3服务器
cat > /soft/code3/index.html <<EOF
<html>
<title>Code3</title>
<body bgcolor="green">
<h1>Code3-8083</h1>
</body>
</html>
EOF

2. 配置后端服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# /etc/nginx/conf.d/backend_servers.conf
server {
listen 8081;
root /soft/code1;
index index.html;
}

server {
listen 8082;
root /soft/code2;
index index.html;
}

server {
listen 8083;
root /soft/code3;
index index.html;
}

3. 配置负载均衡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# /etc/nginx/conf.d/load_balance.conf
upstream node {
server 192.168.69.113:8081;
server 192.168.69.113:8082;
server 192.168.69.113:8083;
}

server {
server_name 192.168.69.113;
listen 80;

location / {
proxy_pass http://node;
include proxy_params;
}
}

4. 验证效果

  • 多次访问,请求会轮询分发到三个后端服务器
  • 可以看到不同颜色的页面(红、蓝、绿)

3.3 Nginx负载均衡状态配置

3.3.1 服务器状态

服务器状态类型

  • 正常(normal):默认状态,正常接收请求
  • down:标记为不可用,不接收请求
  • backup:备份服务器,其他服务器不可用时使用
  • max_fails:最大失败次数
  • fail_timeout:失败超时时间

3.3.2 状态配置示例

基础配置

1
2
3
4
5
upstream load_pass {
server 192.168.56.11:8001 down; # 标记为不可用
server 192.168.56.12:8002 backup; # 备份服务器
server 192.168.56.13:8003 max_fails=1 fail_timeout=10s;
}

完整配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
upstream backend {
# 正常服务器
server 192.168.1.100:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.101:8080 weight=2 max_fails=3 fail_timeout=30s;

# 备份服务器
server 192.168.1.102:8080 backup;

# 标记为不可用
server 192.168.1.103:8080 down;
}

server {
location / {
proxy_pass http://backend;
include proxy_params;
}
}

3.3.3 健康检查

被动健康检查

1
2
3
4
upstream backend {
server 192.168.1.100:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
}

工作原理

  • 请求失败时,失败计数+1
  • 达到max_fails后,标记为不可用
  • fail_timeout后重新尝试

3.4 Nginx负载均衡调度策略

3.4.1 轮询(Round Robin)

默认策略,按顺序依次分配请求。

配置示例

1
2
3
4
5
upstream backend {
server 192.168.1.100:8080;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}

3.4.2 加权轮询(Weighted Round Robin)

根据权重分配请求,权重高的服务器处理更多请求。

配置示例

1
2
3
4
5
upstream load_pass {
server 192.168.56.11:8001;
server 192.168.56.12:8002 weight=5; # 权重5
server 192.168.56.13:8003;
}

权重分配

  • 总权重:1 + 5 + 1 = 7
  • 8001:1/7 ≈ 14%
  • 8002:5/7 ≈ 71%
  • 8003:1/7 ≈ 14%

3.4.3 IP哈希(ip_hash)

根据客户端IP计算哈希值,相同IP总是访问同一服务器(会话保持)。

配置示例

1
2
3
4
5
6
upstream load_pass {
ip_hash; # 启用IP哈希
server 192.168.56.11:8001;
server 192.168.56.12:8002;
server 192.168.56.13:8003;
}

注意事项

  • 如果客户端都走相同代理,会导致某一台服务器连接过多
  • 如果服务器down,会重新hash

3.4.4 URL哈希(url_hash)

根据请求URI计算哈希值,相同URI总是访问同一服务器(缓存友好)。

配置示例

1
2
3
4
5
6
upstream load_pass {
hash $request_uri; # 基于URI的哈希
server 192.168.56.11:8001;
server 192.168.56.12:8002;
server 192.168.56.13:8003;
}

实战测试

1
2
3
4
# 在三台服务器上准备相同的文件
# /soft/code1/url1.html url2.html url3.html
# /soft/code2/url1.html url2.html url3.html
# /soft/code3/url1.html url2.html url3.html

特点

  • 相同URI总是访问同一服务器
  • 适合缓存场景
  • 如果通过代理访问,会影响后端节点接收状态均衡

3.4.5 最少连接(least_conn)

将请求分配给连接数最少的服务器

配置示例

1
2
3
4
5
6
upstream backend {
least_conn; # 最少连接算法
server 192.168.1.100:8080;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}

适用场景

  • 长连接场景
  • 连接持续时间差异大

3.5 Nginx负载均衡TCP配置

3.5.1 TCP负载均衡概述

Nginx四层代理(TCP/UDP)仅能存在于main段,不能放在http段。

应用场景

  • MySQL负载均衡
  • Redis负载均衡
  • SSH负载均衡
  • 其他TCP服务

3.5.2 TCP负载均衡配置

编译Nginx支持TCP代理

1
2
3
4
5
6
7
8
# 下载nginx_tcp_proxy_module
cd /soft/src
git clone https://github.com/yaoweibin/nginx_tcp_proxy_module.git

# 编译Nginx
./configure \
--add-module=/soft/src/nginx_tcp_proxy_module \
# ... 其他参数

或者使用stream模块(Nginx 1.9.0+)

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
# nginx.conf
stream {
# SSH负载均衡
upstream ssh_proxy {
hash $remote_addr consistent;
server 192.168.56.103:22;
}

# MySQL负载均衡
upstream mysql_proxy {
hash $remote_addr consistent;
server 192.168.56.103:3306;
}

# SSH代理服务器
server {
listen 6666;
proxy_connect_timeout 1s;
proxy_timeout 300s;
proxy_pass ssh_proxy;
}

# MySQL代理服务器
server {
listen 5555;
proxy_connect_timeout 1s;
proxy_timeout 300s;
proxy_pass mysql_proxy;
}
}

3.5.3 TCP负载均衡实战

MySQL负载均衡配置

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
stream {
# MySQL主库(写)
upstream mysql_master {
server 192.168.1.100:3306 weight=1;
server 192.168.1.101:3306 weight=1 backup;
}

# MySQL从库(读)
upstream mysql_slave {
least_conn;
server 192.168.1.102:3306 weight=3;
server 192.168.1.103:3306 weight=2;
}

# 主库监听端口
server {
listen 3307;
proxy_pass mysql_master;
proxy_timeout 1s;
proxy_responses 1;
}

# 从库监听端口
server {
listen 3308;
proxy_pass mysql_slave;
proxy_timeout 1s;
proxy_responses 1;
}
}

4. Nginx动静分离

4.1 动静分离概述

4.1.1 动静分离原理

动静分离:通过中间件将动态请求和静态请求进行分离,分离资源,减少不必要的请求消耗,减少请求延时。

架构图

1
2
3
4
5
6
客户端请求

Nginx(反向代理)

├──→ 静态请求 → 静态资源服务器
└──→ 动态请求 → 动态应用服务器

4.1.2 动静分离优势

优势

  • 性能提升:静态资源由Nginx高效处理
  • 资源优化:减少应用服务器压力
  • 高可用:动静分离后,即使动态服务不可用,但静态资源不会受到影响
  • 扩展性:静态资源和动态资源可以独立扩展

4.2 Nginx动静分离应用案例

4.2.1 环境准备

1. 静态资源服务器(192.168.69.113)

1
2
3
4
5
6
7
8
9
10
11
# /etc/nginx/conf.d/static.conf
server {
listen 80;
root /soft/code;
index index.html;

location ~ .*\.(png|jpg|gif)$ {
gzip on;
root /soft/code/images;
}
}

准备静态资源

1
2
# 下载图片
wget -O /soft/code/images/nginx.png http://nginx.org/nginx.png

2. 动态资源服务器(192.168.69.113)

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
# 安装Tomcat
wget -O /soft/package/tomcat9.tar.gz \
http://mirror.bit.edu.cn/apache/tomcat/tomcat-9/v9.0.7/bin/apache-tomcat-9.0.7.tar.gz

mkdir -p /soft/app
tar xf /soft/package/tomcat9.tar.gz -C /soft/app/

# 创建JSP测试页面
cat > /soft/app/apache-tomcat-9.0.7/webapps/ROOT/java_test.jsp <<EOF
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<HTML>
<HEAD>
<TITLE>JSP Test Page</TITLE>
</HEAD>
<BODY>
<%
Random rand = new Random();
out.println("<h1>Random number:</h1>");
out.println(rand.nextInt(99)+100);
%>
</BODY>
</HTML>
EOF

# 启动Tomcat
/soft/app/apache-tomcat-9.0.7/bin/startup.sh

4.2.2 动静分离配置

代理服务器配置(192.168.69.112)

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
# /etc/nginx/conf.d/dynamic_static.conf

# 静态资源upstream
upstream static {
server 192.168.69.113:80;
}

# 动态资源upstream
upstream java {
server 192.168.69.113:8080;
}

server {
listen 80;
server_name 192.168.69.112;

# 默认页面
location / {
root /soft/code;
index index.html;
}

# 静态资源(图片)
location ~ .*\.(png|jpg|gif)$ {
proxy_pass http://static;
include proxy_params;
}

# 动态资源(JSP)
location ~ .*\.jsp$ {
proxy_pass http://java;
include proxy_params;
}
}

4.2.3 动静分离整合页面

创建整合HTML文件

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
<!-- /soft/code/mysite.html -->
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>测试动静分离</title>
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
</head>
<script type="text/javascript">
$(document).ready(function(){
$.ajax({
type: "GET",
url: "http://192.168.69.112/java_test.jsp",
success: function(data) {
$("#get_data").html(data)
},
error: function() {
alert("fail!!,请刷新再试!");
}
});
});
</script>
<body>
<h1>测试动静分离</h1>
<img src="http://192.168.69.112/nginx.png">
<div id="get_data"></div>
</body>
</html>

4.2.4 验证动静分离

测试场景

  1. 正常访问

    • 静态资源(图片)正常显示
    • 动态资源(JSP)正常显示随机数
  2. 停止Nginx

    • 静态内容无法访问
    • 动态内容依旧运行正常(直接访问Tomcat)
  3. 停止Tomcat

    • 静态内容依旧能正常访问
    • 动态内容将不会被请求到

4.3 Nginx手机电脑应用案例

4.3.1 基于User-Agent的负载均衡

根据不同的浏览器和手机,访问不同的服务器

配置示例

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
52
53
54
55
56
57
58
59
60
61
62
http {
# Firefox浏览器
upstream firefox {
server 172.31.57.133:80;
}

# Chrome浏览器
upstream chrome {
server 172.31.57.133:8080;
}

# iPhone手机
upstream iphone {
server 172.31.57.134:8080;
}

# Android手机
upstream android {
server 172.31.57.134:8081;
}

# 默认服务器
upstream default {
server 172.31.57.134:80;
}
}

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

location / {
# Safari浏览器
if ($http_user_agent ~* "Safari") {
proxy_pass http://default;
}

# Firefox浏览器
if ($http_user_agent ~* "Firefox") {
proxy_pass http://firefox;
}

# Chrome浏览器
if ($http_user_agent ~* "Chrome") {
proxy_pass http://chrome;
}

# iPhone手机
if ($http_user_agent ~* "iphone") {
proxy_pass http://iphone;
}

# Android手机
if ($http_user_agent ~* "android") {
proxy_pass http://android;
}

# 其他浏览器访问默认规则
proxy_pass http://default;
include proxy_params;
}
}

4.3.2 基于路径的负载均衡

根据访问不同目录,代理不同的服务器

方案1:location配置

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
# 静态资源服务器
upstream static_pools {
server 10.0.0.9:80 weight=1;
}

# 上传服务器
upstream upload_pools {
server 10.0.0.10:80 weight=1;
}

# 默认动态服务器
upstream default_pools {
server 10.0.0.9:8080 weight=1;
}

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

# 默认动态请求
# URL: http://www.example.com/
location / {
proxy_pass http://default_pools;
include proxy_params;
}

# 静态资源
# URL: http://www.example.com/static/
location /static/ {
proxy_pass http://static_pools;
include proxy_params;
}

# 上传文件
# URL: http://www.example.com/upload/
location /upload/ {
proxy_pass http://upload_pools;
include proxy_params;
}
}

方案2:if语句实现

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
upstream static_pools {
server 10.0.0.9:80 weight=1;
}

upstream upload_pools {
server 10.0.0.10:80 weight=1;
}

upstream default_pools {
server 10.0.0.9:8080 weight=1;
}

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

location / {
# 静态资源
if ($request_uri ~* "^/static/(.*)$") {
proxy_pass http://static_pools/$1;
}

# 上传文件
if ($request_uri ~* "^/upload/(.*)$") {
proxy_pass http://upload_pools/$1;
}

# 默认动态请求
proxy_pass http://default_pools;
include proxy_params;
}
}

4.3.3 基于设备类型的优化配置

移动端和PC端分离

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
# PC端服务器
upstream pc_backend {
server 192.168.1.100:8080;
}

# 移动端服务器
upstream mobile_backend {
server 192.168.1.101:8080;
}

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

location / {
# 移动设备
if ($http_user_agent ~* "(mobile|android|iphone|ipad)") {
proxy_pass http://mobile_backend;
break;
}

# PC设备
proxy_pass http://pc_backend;
include proxy_params;
}
}

5. 综合实战案例

5.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
46
47
48
49
50
51
52
# 后端服务器组
upstream web_backend {
least_conn;
server 192.168.1.100:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.101:8080 weight=2 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8080 weight=1 max_fails=3 fail_timeout=30s backup;
}

# 静态资源服务器
upstream static_backend {
server 192.168.1.200:80;
server 192.168.1.201:80;
}

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

# 静态资源
location ~ .*\.(jpg|jpeg|png|gif|css|js|woff|woff2)$ {
proxy_pass http://static_backend;
include proxy_params;

# 缓存配置
expires 7d;
add_header Cache-Control "public, immutable";
}

# 动态请求
location / {
proxy_pass http://web_backend;
include proxy_params;

# 额外配置
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;

# 超时配置
proxy_connect_timeout 30s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}

# API接口
location /api/ {
proxy_pass http://web_backend;
include proxy_params;

# API特殊配置
proxy_set_header Content-Type "application/json";
}
}

5.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
# 主服务器组
upstream primary_backend {
ip_hash;
server 192.168.1.100:8080;
server 192.168.1.101:8080;
}

# 备用服务器组
upstream backup_backend {
server 192.168.1.200:8080;
}

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

location / {
# 尝试主服务器组
proxy_pass http://primary_backend;
include proxy_params;

# 如果主服务器组失败,使用备用服务器组
proxy_next_upstream error timeout http_500 http_502 http_503;
proxy_next_upstream_tries 2;
}
}

6. 总结

6.1 核心要点

  1. 代理服务类型:正向代理、反向代理
  2. 代理配置语法:proxy_pass、proxy_buffering、proxy_set_header等
  3. 负载均衡:upstream配置、调度策略、状态配置
  4. TCP负载均衡:stream模块、四层代理
  5. 动静分离:静态资源、动态资源分离

6.2 架构师建议

  1. 代理选择

    • 正向代理:内网访问外网
    • 反向代理:负载均衡、高可用
  2. 负载均衡策略

    • 一般场景:轮询或加权轮询
    • 需要会话保持:ip_hash
    • 缓存友好:url_hash
    • 长连接:least_conn
  3. 动静分离

    • 静态资源由Nginx直接处理
    • 动态请求转发到应用服务器
    • 提高整体性能

6.3 最佳实践

  1. 标准化:统一代理配置标准
  2. 模块化:使用proxy_params统一配置
  3. 监控化:监控后端服务器健康状态
  4. 文档化:维护配置文档和架构图

相关文章