Nginx反向代理

一、引言:为什么你的架构离不开反向代理?

想象一下,你正在开发一个应用,前端是 React/Vue,后端是 Java/Go/Node.js。在开发阶段,它们运行在不同的端口上(如 30008080),这导致了恼人的跨域问题

再想象一下,你的应用用户量激增,单台后端服务器已经不堪重负,你需要引入多台服务器来分担负载。

还有,你希望隐藏后端服务器的真实 IP 和技术栈,以增加系统的安全性。

所有这些问题的答案,都指向同一个核心技术------Nginx 反向代理

它就像一个不知疲倦的"全能门卫",站在你的应用最前方,负责接收所有请求,智能地将其分发给后端服务,并将结果安全地返回给用户。本文将带你从原理到实战,彻底掌握这项必备技能。

💡 核心价值
学会 Nginx 反向代理,你就掌握了构建高可用、高性能、安全的现代 Web 架构的第一块基石


二、正向代理 vs. 反向代理:一张图看懂区别

很多初学者容易混淆这两个概念,其实它们的服务对象完全不同。

  • 正向代理 (Forward Proxy)

    • 服务对象客户端
    • 作用:客户端通过代理去访问外部网络(如翻墙、公司内网访问外网)。服务器只知道代理的 IP,不知道真实客户端是谁。
    • 类比:代购。你(客户端)委托代购(代理)去国外买东西(服务器)。
  • 反向代理 (Reverse Proxy)

    • 服务对象服务器
    • 作用:客户端直接访问代理,代理再将请求转发给内部的一台或多台真实服务器。客户端只知道代理的 IP,不知道后端服务器的存在。
    • 类比:公司前台。访客(客户端)只和前台(代理)打交道,前台再根据需求将访客引导到具体的部门(后端服务器)。

Nginx 的核心角色就是反向代理


三、核心指令:proxy_pass

proxy_pass 是 Nginx 反向代理功能的心脏。它的作用就是告诉 Nginx:"把匹配到这个 location 的请求,转发到我指定的地址去"。

基本语法

复制代码
location /some/path/ {
    proxy_pass http://backend_server;
}

关键细节:URI 的处理

proxy_pass 后面的 URL 是否以 / 结尾,会直接影响转发时的 URI。

场景 :客户端请求 http://proxy.com/api/users

  • 情况一:proxy_pass/ 结尾

    复制代码
    location /api/ {
        proxy_pass http://192.168.1.10:8080/; # 注意结尾的 /
    }

    转发结果http://192.168.1.10:8080/users

    解释/api/ 被替换成 /,所以 /api/users 变成了 /users

  • 情况二:proxy_pass 不以 / 结尾

    复制代码
    location /api/ {
        proxy_pass http://192.168.1.10:8080; # 没有结尾的 /
    }

    转发结果http://192.168.1.10:8080/api/users

    解释 :整个原始 URI (/api/users) 会被完整地附加到 proxy_pass 的 URL 后面。

最佳实践 :为了精确控制后端接收到的路径,强烈建议使用第一种方式(带 / ,并在 location 中明确匹配前缀。


四、生产级配置:不可或缺的请求头

仅仅使用 proxy_pass 是远远不够的。后端服务器需要知道真实的客户端信息,否则日志、安全策略、业务逻辑都会出错。

必须设置的三大请求头

复制代码
location / {
    proxy_pass http://backend;

    # 1. 传递原始Host头
    # 后端可能根据域名做不同处理(如多租户)
    proxy_set_header Host $host;

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

    # 3. 记录完整的代理链路(最重要!)
    # 如果有多层代理,这个头会追加IP,形成链路
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
  • $host : 客户端请求中的 Host 头。
  • $remote_addr: 直接与 Nginx 建立连接的客户端 IP。
  • $proxy_add_x_forwarded_for : 这是一个智能变量。如果请求中已有 X-Forwarded-For 头,它会在此基础上追加 $remote_addr;如果没有,则直接创建该头并赋值为 $remote_addr

重要提示 :后端代码必须从 X-Forwarded-For 头中获取真实 IP,而不是直接读取 TCP 连接的对端 IP(那会是 Nginx 的 IP)。


五、六大经典应用场景

场景一:解决前后端分离的跨域问题

痛点 :前端 localhost:3000 无法直接调用后端 localhost:8080 的 API。

解决方案:在前端开发服务器或 Nginx 中配置代理。

复制代码
server {
    listen 80;
    server_name localhost;

    # 静态资源
    location / {
        root /path/to/frontend/dist;
        try_files $uri $uri/ /index.html;
    }

    # API 代理,解决跨域
    location /api/ {
        proxy_pass http://localhost:8080/; # 转发到后端
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

现在,前端只需请求 /api/users,Nginx 会将其无缝代理到后端,浏览器认为这是同源请求,跨域问题迎刃而解。

场景二:负载均衡

通过 upstream 块定义一组后端服务器,Nginx 会自动进行负载均衡。

复制代码
upstream myapp {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080 backup; # 备份节点
}

server {
    location / {
        proxy_pass http://myapp; # 转发到 upstream
        proxy_set_header ...; # 请求头略
    }
}

场景三:HTTPS/SSL 终结

将 HTTPS 的加解密工作交给 Nginx,后端服务只需处理简单的 HTTP 流量,极大减轻后端压力。

复制代码
server {
    listen 443 ssl;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/privkey.pem;

    location / {
        proxy_pass http://backend; # 转发的是HTTP!
        proxy_set_header X-Forwarded-Proto $scheme; # 告诉后端原始是https
        proxy_set_header ...;
    }
}

场景四:API 网关与路由

作为微服务架构的统一入口,根据路径将请求路由到不同的服务。

复制代码
location /user/ {
    proxy_pass http://user-service/;
}
location /order/ {
    proxy_pass http://order-service/;
}
location /payment/ {
    proxy_pass http://payment-service/;
}

场景五:安全防护与隐藏后端

对外只暴露 Nginx 的 IP,后端服务器可以部署在内网,不直接暴露在公网,增加了攻击难度。

场景六:缓存静态/动态内容

Nginx 可以缓存后端返回的内容,对于不常变化的 API 或页面,能极大提升响应速度并降低后端负载。

复制代码
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m;

location /api/slow-data {
    proxy_cache my_cache;
    proxy_cache_valid 200 5m; # 缓存成功响应5分钟
    proxy_pass http://backend;
}

六、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
优化Henry6 小时前
LTE站点8通道RRU单通道驻波异常导致小区服务降级案例分析
运维·服务器·5g·信息与通信
Keano Reurink7 小时前
SEO数据管道:用Airflow搭建自动化工作流
运维·人工智能·爬虫·搜索引擎·自动化·ai编程·seo
李昊哲小课7 小时前
Ubuntu 在线安装最新版 Nginx
nginx·ubuntu
阿杰技术8 小时前
SillyTavern(酒馆)AI聊天:本地与云服务器部署全攻略
运维·服务器
网络与设备以及操作系统学习使用者8 小时前
vi与vim在openEuler中的差异及应用
linux·运维·网络·学习·vim
ylscode8 小时前
巨齿鲨突袭GitHub:5500余仓库沦陷,开源供应链安全防线再遭重创
运维·服务器·网络·安全·安全威胁分析
shy_snow8 小时前
Nginx解决跨域问题
运维·nginx
c++逐梦人8 小时前
epoll ET服务器(Reactor模式)
运维·服务器·php
牛奔9 小时前
codebuddy 桌面版 如何配置自己的模型
运维·服务器·开发语言·php