Nginx 服务器反向代理实战指南

文章目录

一、反向代理概述

1. 正向代理:为客户端赋能的中间层

正向代理(Forward Proxy)的核心职责是代理客户端发起请求,其本质在于隐藏客户端的真实身份。

生活化类比------代买奶茶:

假设你(客户端)因为某些原因无法亲自前往奶茶店(服务器),于是委托室友(正向代理)代为购买。奶茶店只知道是室友来买的,并不知道背后真正的消费者是你。

这就是正向代理的核心特征:代理代表客户端

正向代理: 替客户端办事,隐藏客户端

正向代理生活案例: 代买奶茶

  • 你:客户端
  • 室友:正向代理
  • 奶茶店:服务器

你懒得下楼/小区不让出去,让室友帮你去买奶茶。

奶茶店只知道是你室友来买的, 不知道背后真正买的人是你。

◉这就是正向代理: 代理代表客户端。

2. 反向代理:为服务器守护的中间层

反向代理(Reverse Proxy)的核心职责是代理后端服务器接收请求,其本质在于隐藏后端服务器的真实信息。

生活化类比------餐厅前台点餐:

你走进餐厅,只需在前台点餐(客户端与前台交互),无需关心后厨哪位厨师(真实服务器)为你烹饪。前台将订单传递给后厨,做好后再由前台端给你。你全程只需面对前台,无需知晓背后是哪位厨师在操作。

这就是反向代理的核心特征:代理代表服务器

反向代理生活案例: 餐厅前台点餐

  • 你:客户端
  • 前台小姐姐:反向代理
  • 后厨厨师们:真实服务器

你进店只跟前台点餐,不用管是哪个厨师做的。

前台把单子传给后厨,做好了再端给你。

你全程只面对前台, 不知道、也不用关心背后是哪个厨师在干活。

②这就是反向代理: 代理代表服务器。

3. 反向代理的技术定义

反向代理(Reverse Proxy)是指代理外部用户的请求到内部指定的后端服务器,并将处理结果返回给用户。客户端不直接与后端服务器通信,而是通过反向代理服务器进行中转,从而有效隐藏后端服务器的 IP 地址。

4. 反向代理的核心能力

反向代理的主要价值体现在以下四个维度:

  • 负载均衡:Nginx 可将传入的请求智能分发至多个后端服务器,均衡各节点的负载压力,显著提升系统的整体性能与可靠性。

  • 缓存功能:Nginx 可对静态文件或动态页面进行缓存,有效减轻后端服务器的处理压力,大幅缩短响应延迟。

  • 动静分离:将动态生成的内容(如 PHP、Python、Node.js 等)与静态资源(如 HTML、CSS、JavaScript、图片、视频等)分别部署在不同的服务器或路径上,实现资源的最优调度。

  • 多站点代理:Nginx 支持代理多个域名或虚拟主机,将不同请求转发至不同的后端服务器,实现多站点共享同一端口的灵活部署方案。

二、Location 配置详解

1. 配置语法基础

Nginx 通过 location 匹配规则与 proxy_pass 反向代理指令的配合,实现完整的反向代理功能。其匹配本质可概括为:URL 路径匹配 → 命中对应规则 → 转发至指定后端地址

  • location 定义匹配路径
  • proxy_pass 指定后端服务地址
bash 复制代码
http {
    # 后端服务可配置 upstream 集群(推荐,支持负载均衡)
    upstream backend_nginx {
        nginx 192.168.1.100:8080;  # 后端服务1
        nginx 192.168.1.101:8080;  # 后端服务2(多节点自动轮询负载均衡)
    }

    server {
        listen 80;  # Nginx 监听端口
        server_name localhost;  # 访问域名/IP

        # 1. 匹配所有请求(兜底规则)
        location / {
            proxy_pass http://backend_nginx;  # 转发至 upstream 集群
            # 必加的反向代理核心参数(传递客户端真实信息、适配后端服务)
            proxy_set_header Host $host;                # 传递客户端访问的域名
            proxy_set_header X-Real-IP $remote_addr;    # 传递客户端真实IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #传递IP链路
            proxy_set_header X-Forwarded-Proto $scheme; # 传递请求协议( http/https) 
        }
        # 2. 匹配特定路径(如 /api 开头的请求,单独转发)
        location /api/ {
            proxy_pass http://192.168.1.102:9090/;  # 后端地址末尾带 /,会剔除匹配的/api/
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

2. 五大 Location 匹配规则

Nginx 的 location 匹配遵循以下优先级体系:

优先级 匹配类型 语法 说明
1(最高) 精确匹配(=) location = /path { ... } URL 必须与路径完全一致
2 前缀匹配(^~) location ^~ /path { ... } URL 以指定路径开头即命中,跳过正则匹配
3 正则匹配(~ / ~*) location ~ /regex { ... } URL 符合正则表达式即命中,按定义顺序匹配
4 普通前缀匹配 location /path { ... } URL 以指定路径开头即命中,多规则按路径最长优先
5(最低) 通用匹配(/) location / { ... } 兜底规则,所有未命中请求均匹配
  1. 后端匹配逻辑: URL 路径 → 按 location 优先级命中规则 → 由规则内的 proxy_pass 转发至对应后端

  2. 优先级:精确匹配(=)> 前缀匹配(^~)> 正则匹配(/*)> 普通前缀 >兜底(/);

  3. URL 重构关键: proxy_pass 末尾是否带 /,决定是否剔除 location 匹配的路径前缀。

规则一:精确匹配(=)
  • 语法location = /path { ... }
  • 逻辑 :仅当请求 URL 与 /path 完全一致时命中,优先级最高。
  • 示例
bash 复制代码
# 仅匹配 http://localhost/login,不匹配 /login?a=1、/login/xxx
location = /login {
    proxy_pass http://backend_login:8080;
}
规则二:前缀匹配(^~)
  • 语法location ^~ /path { ... }
  • 逻辑 :URL 以 /path 开头即命中,优先级仅次于精确匹配,会跳过正则匹配
  • 用途 :优先匹配静态资源(如 /static/img)或特定业务路径,避免被正则规则拦截。
  • 示例
bash 复制代码
# 匹配所有 /static 开头的请求(如 /static/css/main.css、/static/img/1.jpg)
location ^~ /static/ {
    proxy_pass http://backend_static:80;
}
规则三:正则匹配(~ / ~*)
  • 语法
    • 区分大小写:location ~ /regex { ... }(如 /API 不匹配 /api 规则)
    • 不区分大小写:location ~* /regex { ... }(如 /API/api 均匹配)
  • 逻辑:URL 符合正则表达式即命中,优先级低于前缀匹配(^~),多个正则规则按定义顺序匹配,先命中先生效。
  • 示例
bash 复制代码
# 匹配所有 .jpg、.png、.gif 结尾的图片请求(不区分大小写)
location ~* \.(jpg|png|gif)$ {
    proxy_pass http://backend_img:80;
}
规则四:普通前缀匹配(无符号)
  • 语法location /path { ... }
  • 逻辑 :URL 以 /path 开头即命中,优先级低于正则匹配,多个普通前缀规则按"路径最长"优先命中。
  • 示例
bash 复制代码
# 规则1:匹配 /api/xxx(路径长度3)
location /api/ {
    proxy_pass http://backend_api:9090;
}
# 规则2:匹配 /api/user/xxx(路径长度7,比规则1长,优先命中)
location /api/user/ {
    proxy_pass http://backend_user:9090;
}
规则五:通用匹配(/)
  • 语法location / { ... }
  • 逻辑:所有未被上述规则命中的请求,都会匹配此规则(兜底),优先级最低。
  • 用途:通常作为全局反向代理,转发所有默认请求到主后端服务。

3. proxy_pass 路径重构机制

proxy_pass 末尾是否携带 /,会直接改变转发到后端的 URL 路径,这是后端匹配后"URL 重构"的核心机制。

场景一:proxy_pass 末尾带 /

  • 逻辑 :转发时,会剔除 location 匹配的路径前缀,将剩余路径拼接在后端地址后。
  • 示例
bash 复制代码
# location 匹配 /api/,proxy_pass 末尾带 /
location /api/ {
    proxy_pass http://192.168.1.102:9090/;
}
# 实际转发逻辑:
# 客户端请求 http://localhost/api/user/list
# → 后端接收 http://192.168.1.102:9090/user/list

场景二:proxy_pass 末尾不带 /

  • 逻辑 :转发时,会保留 location 匹配的路径前缀,直接拼接在后端地址后。
  • 示例
bash 复制代码
# location 匹配 /api/,proxy_pass 末尾不带 /
location /api/ {
    proxy_pass http://192.168.1.102:9090;
}
# 实际转发逻辑:
# 客户端请求 http://localhost/api/user/list
# → 后端接收 http://192.168.1.102:9090/api/user/list

4. 综合配置示例

以下是一个完整的 Nginx 反向代理配置文件,涵盖了五种匹配规则的综合运用:

bash 复制代码
http {
    upstream backend_main {server 192.168.1.200:8080;}
    upstream backend_api {server 192.168.1.201:9090;}
    upstream backend_static {server 192.168.1.202:80;}
    upstream backend_login {server 192.168.1.203:8080;}

    server {
        listen 80;
        server_name localhost;

        # 1. 精确匹配:仅 /login → 后端 login 服务
        location = /login {
            proxy_pass http://backend_login;
            proxy_set_header Host $host;
        }

        # 2. 前缀匹配:/static/ 开头 → 后端静态服务(跳过正则)
        location ^~ /static/ {
            proxy_pass http://backend_static/;
            proxy_set_header Host $host;
        }

        # 3. 正则匹配:图片后缀 → 后端静态服务
        location ~* \.(jpg|png|gif)$ {
            proxy_pass http://backend_static;
            proxy_set_header Host $host;
        }

        # 4. 普通前缀:/api/ 开头 → 后端 api 服务
        location /api/ {
            proxy_pass http://backend_api/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

        # 5. 兜底匹配:所有未命中的请求 → 主后端服务
        location / {
            proxy_pass http://backend_main;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

5. 请求匹配流程

客户端请求 URL 命中的 Location 规则 转发至后端的 URL 对应后端服务
http://localhost/login = /login http://192.168.1.203:8080/login backend_login
http://localhost/static/css/main.css ^~ /static/ http://192.168.1.202:80/css/main.css backend_static
http://localhost/img/1.jpg ~* .(jpg png gif)$
http://localhost/api/user/info /api/ http://192.168.1.201:9090/user/info backend_api
http://localhost/index / http://192.168.1.200:8080/index backend_main

三、反向代理实践环境搭建

1. 环境架构

本实践环境基于 CentOS 7 搭建,包含以下节点:

主机名 IP 地址 服务器角色
client.laogao.cloud 10.1.8.11 客户端(测试服务器)
proxy.laogao.cloud 10.1.8.20 Nginx 代理服务器
nginx1.laogao.cloud 10.1.8.21 Nginx Web 服务器
nginx2.laogao.cloud 10.1.8.22 Nginx Web 服务器
nginx3.laogao.cloud 10.1.8.23 Nginx Web 服务器

2. 基础网络配置

在各节点上执行以下命令完成主机名与 IP 配置:

bash 复制代码
# client 节点
hostnamectl set-hostname client.laogao.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.11/24 ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes
nmcli connection up ens33

# proxy 节点
hostnamectl set-hostname client.laogao.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.20/24 ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes
nmcli connection up ens33

# nginx1 节点
hostnamectl set-hostname client.laogao.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.21/24 ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes
nmcli connection up ens33

# nginx2 节点
hostnamectl set-hostname client.laogao.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.22/24 ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes
nmcli connection up ens33

# nginx3 节点
hostnamectl set-hostname client.laogao.cloud
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.23/24 ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes
nmcli connection up ens33

3. 配置 /etc/hosts

在所有节点上执行以下配置:

bash 复制代码
# 所有节点
[root@所有节点 ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
############ proxy ##################
10.1.8.11 client.laogao.cloud client
10.1.8.20 www.laogao.cloud www
10.1.8.20 proxy.laogao.cloud proxy
10.1.8.21 nginx1.laogao.cloud nginx1
10.1.8.22 nginx2.laogao.cloud nginx2
10.1.8.23 nginx3.laogao.cloud nginx3

4. 后端 Nginx 服务器部署

在 proxy、nginx1、nginx2、nginx3 节点上执行以下操作:

bash 复制代码
# 安装 EPEL 源
[root@proxy,nginx1,nginx2,nginx3 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

# 安装 Nginx
[root@proxy,nginx1,nginx2,nginx3 ~]# yum -y install nginx

# 启动并启用 Nginx 服务
[root@proxy,nginx1,nginx2,nginx3 ~]# systemctl enable nginx --now

# 配置防火墙
[root@proxy,nginx1,nginx2,nginx3 ~]# firewall-cmd --add-service=http --permanent
[root@proxy,nginx1,nginx2,nginx3 ~]# firewall-cmd --add-service=http

为各后端节点准备主页内容:

bash 复制代码
# nginx1 节点
[root@nginx1 ~]# echo "Welcome to $(hostname)" > /usr/share/nginx/html/index.html

# nginx2 节点
[root@nginx2 ~]# echo "Welcome to $(hostname)" > /usr/share/nginx/html/index.html

# nginx3 节点
[root@nginx3 ~]# echo "Welcome to $(hostname)" > /usr/share/nginx/html/index.html

客户端验证各后端节点:

bash 复制代码
[root@nginx-client ~]# curl http://nginx1.laogao.cloud/
Welcome to nginx1.laogao.cloud

[root@nginx-client ~]# curl http://nginx2.laogao.cloud/
Welcome to nginx2.laogao.cloud

[root@nginx-client ~]# curl http://nginx3.laogao.cloud/
Welcome to nginx3.laogao.cloud

5. 后端 Nginx 服务器部署

bash 复制代码
# 准备主页-代理节点
[root@proxy ~]# echo Welcome to www.laogao.cloud > /usr/share/nginx/html/index.html

[root@proxy ~]# mkdir /var/nginx
[root@proxy ~]# echo "Hello, Nginx" > /var/nginx/index.html
[root@proxy ~]# echo "Hello, laogao" > /var/nginx/test.txt
[root@proxy ~]# cp /usr/share/nginx/html/nginx-logo.png /var/nginx/ [root@proxy ~]# ls /var/nginx/
index.html  nginx-logo.png  test.txt

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
    listen  80;
    server_name www.laogao.cloud;

    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html; 
    }
}
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

# 测试
[root@nginx-client ~]# curl http://www.laogao.cloud/ Hello, Nginx
[root@nginx-client ~]# curl http://www.laogao.cloud/test.txt Hello, laogao

访问 www.laogao.cloud/nginx-logo.png,系统会返回以下页面:

五、反向代理基础实践

代理本地实践

环境准备

bash 复制代码
[root@proxy ~]# mkdir /var/nginx/nginx{1,2}
[root@proxy ~]# echo "Hello, I'm here /var/nginx/nginx1" > /var/nginx/nginx1/index.html
[root@proxy ~]# echo "Hello, I'm here /var/nginx/nginx2" > /var/nginx/nginx2/index.html

[root@proxy ~]# mkdir /var/nginx{1,2}
[root@proxy ~]# echo "Hello, Nginx1" > /var/nginx1/index.html
[root@proxy ~]# echo "Hello, Nginx2" > /var/nginx2/index.html [root@proxy ~]# tree /var/nginx*
/var/nginx
├── index.html
├── nginx1
│   └── index.html ├── nginx2
│   └── index.html ├── nginx-logo.png └── test.txt
/var/nginx1
└── index.html /var/nginx2
└── index.html

2 directories, 7 files
[root@proxy ~]# \
>for path1 in www{1..2} do
>for path2 in nginx{1..2} do
>mkdir -p /var/$path1/$path2
>echo "Hello, I'm here /var/$path1/$path2" > >/var/$path1/$path2/index.html 
>done
>done

[root@proxy ~]# tree /var/www*
/var/www1
├── nginx1
│   └── index.html └── nginx2
└── index.html /var/www2
├── nginx1
│   └── index.html └── nginx2
└── index.html

4 directories, 4 files

基本测试

bash 复制代码
[root@nginx-client ~]# curl http://www.laogao.cloud/ Hello, Nginx
# 显示结果是目录/var/nginx/nginx1中内容
[root@nginx-client ~]# curl http://www.laogao.cloud/nginx1/ Hello, I'm here /var/nginx/nginx1
# 显示结果是目录/var/nginx/nginx2中内容
[root@nginx-client ~]# curl http://www.laogao.cloud/nginx2/ Hello, I'm here /var/nginx/nginx2
  • 实践 1:无符号匹配访问测试
bash 复制代码
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
    listen  80;
    server_name www.laogao.cloud;

    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html; 
    }
    # 匹配/nginx1时,/var目录下找nginx1,完整路径是/var/nginx1
    location /nginx1 {
        root /var;
        # 等效于下面的 alias 语句,必须使用绝对路径
        # alias /var/nginx1;
        index index.html;
    }
}

# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

# 访问测试
# nginx1 后面必须添加 / 符号
[root@nginx-client ~]# curl http://www.laogao.cloud/nginx1/ Hello, Nginx1
# 显示结果是目录/var/nginx1中内容

# nginx2 后面必须添加 / 符号
[root@nginx-client ~]# curl http://www.laogao.cloud/nginx2/ Hello, I'm here /var/nginx/nginx2
# 显示结果是目录/var/nginx/nginx2中内容
  • 实验结果:无符号匹配的优先级高于默认的 /

  • 实践 2:正则表达式匹配访问测试

    • 实验结果:正则表达式匹配的优先级高于无符号匹配。
bash 复制代码
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
    listen  80;
    server_name www.laogao.cloud;

    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }
    # 匹配/nginx1时,/var目录下找nginx1,完整路径是/var/nginx1
    location /nginx1 {
        root /var;
        # 等效于下面的 alias 语句,必须使用绝对路径
        # alias /var/nginx1;
        index index.html; }

    # 正则表达式匹配 /nginx.*
    location ~ /nginx.* { 
        root /var/www1;
        index index.html;
    }
}

# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

# nginx1 后面必须添加 / 符号
[root@nginx-client ~]# curl http://www.laogao.cloud/nginx1/ Hello, I'm here /var/www1/nginx1
# 显示结果是目录/var/www1/nginx1中内容

# nginx2 后面必须添加 / 符号
[root@nginx-client ~]# curl http://www.laogao.cloud/nginx2/ Hello, I'm here /var/www1/nginx2
# 显示结果是目录/var/www1/nginx2中内容
  • 实践 3:精确匹配访问测试
    • 实验结果:精确匹配的优先级高于正则表达式。
bash 复制代码
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
    listen  80;
    server_name www.laogao.cloud;

    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html; 
    }

    # 匹配/nginx1时,/var目录下找nginx1,完整路径是/var/nginx1
    location /nginx1 {
        root /var;
        # 等效于下面的 alias 语句,必须使用绝对路径
        # alias /var/nginx1;
        index index.html; 
    }
    # 正则表达式匹配 /nginx.*
    location ~ /nginx.* { 
        root /var/www1;
        index index.html; 
    }

    # 精确匹配
    location = /nginx2/index.html { 
        root /var/www2;
        index index.html;
    }
}

# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

# nginx1 后面必须添加 / 符号
[root@nginx-client ~]# curl http://www.laogao.cloud/nginx1/ Hello, I'm here /var/www1/nginx1
# 显示结果是目录/var/www1/nginx1中内容

# nginx2 后面必须添加 / 符号
[root@nginx-client ~]# curl http://www.laogao.cloud/nginx2/ Hello, I'm here /var/www2/nginx2
# 显示结果是目录/var/www2/nginx2中内容

六、总结

Nginx 作为业界领先的高性能 HTTP 服务器与反向代理工具,凭借其事件驱动的异步架构,在处理高并发请求时展现出卓越的性能表现。本文系统性地梳理了反向代理的核心概念,从正向代理与反向代理的本质差异出发,深入剖析了 Nginx 在负载均衡、缓存加速、动静分离及多站点代理等关键场景中的工程实践。通过对 Location 五大匹配规则的优先级体系与 proxy_pass 路径重构机制的详细解读,结合综合配置示例与匹配流程表,帮助读者建立起完整的请求转发逻辑认知。在实践层面,本文从零搭建了一套包含五台节点的完整反向代理实验环境,涵盖网络配置、Nginx 部署、代理规则验证等全链路操作,为读者提供了可复现的实战参考。掌握 Nginx 反向代理技术,不仅是构建高可用 Web 架构的基石,更是迈向现代云原生基础设施运维的关键一步。

相关推荐
峰向AI1 小时前
316k+ Star 史上第二热门项目,没有一行代码
github
dong_junshuai1 小时前
每天一个开源项目#86 ECC:245K星的 Agent 工程操作层
开源·github·agent
Natural3 小时前
混合检索 + RRF + Rerank 实战评测:三条路线在 47 个真实问题上的取舍
github
一点一木5 小时前
憋了7周没动静,OpenClaw 2.0带着16000个PR杀回来了
人工智能·github
一点一木8 小时前
🚀 2026 年 8 月 GitHub 十大热门项目排行榜 🔥
人工智能·github
痕迹运维9 小时前
Nginx SFTP代理
nginx
BreezeJiang9 小时前
为什么生成了 dist,项目还是可能跑不起来?从一个 React + Express + MySQL 项目看部署闭环
nginx·react.js
Darling噜啦啦10 小时前
前端到上线全流程:从买服务器到 Nginx 反向代理,搞懂全栈部署
nginx·全栈
BreezeJiang10 小时前
从域名到 Node.js:一次云服务器请求经过了哪些层?
服务器
烬羽10 小时前
我把"时间胶囊"部署上腾讯云宝塔,跨域从根源消失了
nginx·node.js·全栈