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 架构的基石,更是迈向现代云原生基础设施运维的关键一步。

相关推荐
逛逛GitHub1 小时前
在 Codex 中用这 4 个 SKill,让你拍的照片变高级。
github
刚入门的大一新生1 小时前
Linux-Linux第一个系统程序-进度条
linux·运维·服务器
村雨遥2 小时前
覆盖提交不等于删除,这才是彻底清除 Git 历史的正确姿势
git·github
FlightYe2 小时前
linux系统编程(八):阻塞与非阻塞IO对比
android·linux·运维·服务器·github·vim
kaixin_啊啊2 小时前
GitHub 开源 Qwen-MM-Plugins 小白入门,给 Codex 装上多模态工具箱
开源·github
淮北4942 小时前
ubuntu22 默认输入法调整频率
运维·服务器·git·ubuntu·elasticsearch
土星云SaturnCloud2 小时前
大坝结构安全智能诊断:土星云边缘计算全周期管控实践
服务器·人工智能·安全·ai·边缘计算
Percep_gan2 小时前
切割服务器日志
运维·服务器
农村小镇哥3 小时前
C#读取CSV文件的方法
服务器·数据库·c#