CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Nginx 反向代理入门/课时/反向代理基础
RawBlame
课时目录12 节

Nginx 反向代理入门

  1. 01Nginx 是什么
  2. 02安装与 nginx -t
  3. 03配置文件结构
  4. 04静态资源
  5. 05反向代理基础
  6. 06双 upstream 架构
  7. 07HTTPS 与证书
  8. 08安全响应头
  9. 09缓存与性能
  10. 10负载均衡
  11. 11Nginx 与 Ingress
  12. 12综合练习

反向代理基础

proxy_pass、proxy_set_header、WebSocket 升级。

35 分钟

反向代理基础

这一课你将能做到

  1. 正确写出两种 proxy_pass(末尾有/无 /),并推演 /api/tracks 到达 Spring Boot 后的路径
  2. 配齐 Host、X-Real-IP、X-Forwarded-For、X-Forwarded-Proto,说明 Spring / Next 为何需要它们
  3. 为经 Nginx 的 Next 开发态补上 Upgrade / Connection,避免 WebSocket/HMR 失败

为什么要学

反向代理是本 track 的核心技能:CodeRoadMap 所有公网 /api 与页面流量都经 proxy_pass 进入上游。
写错尾斜杠 → 404;丢了转发头 → 后端以为自己是 http、限流记错 IP、redirect 跳错域;缺 Upgrade → 本地经 Nginx 调试时热更新挂掉。
本课把「转发语义 + 必备头 + 超时/体大小」一次钉牢,下一课再组装完整双 upstream。

先建立图像

客户端请求
  Host: www.coderoadmap.cn
  URL:  /api/tracks
        │
        ▼
location /api/  +  proxy_pass http://backend/;
        │  去掉 /api/ 前缀
        ▼
上游收到
  URL:  /tracks
  额外头: X-Forwarded-Proto=https, X-Real-IP=客户端, …
写法行为直觉本站用法
proxy_pass http://upstream/;(有尾 /)常与 location 前缀替换相关/api/ → 剥前缀进 Spring
proxy_pass http://upstream;(无尾 /)更常保留原 URI/ → 原样进 Next

人话:proxy_pass 的尾斜杠像「是否撕掉信封上的部门代号再投递」。撕错了,收件人桌牌对不上。

跟着做

步骤 1:读官方 proxy_pass 说明

打开 ngx_http_proxy_module — proxy_pass,关注:当 proxy_pass 带 URI 时,location 匹配部分会被替换。
用中文记:「带路径的 proxy_pass 会改写 URI;只写 scheme+host(可含 upstream 名)时通常保留原请求 URI。」

步骤 2:对照生产两段

打开 deploy/nginx/prod.conf.example:

location /api/ {
    # 尾 / :/api/tracks → 上游 /tracks(Spring 映射不含 /api 前缀)
    proxy_pass http://coderoadmap_backend/;
    proxy_http_version 1.1;
    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;
}

location / {
    # 无尾 / :/tracks/foo → 上游 /tracks/foo
    proxy_pass http://coderoadmap_platform;
    proxy_http_version 1.1;
    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;
    # Next 开发 HMR / WebSocket 需要
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

在笔记推演三行:

  1. /api/auth/login → :8080/auth/login
  2. /api/tracks → :8080/tracks
  3. /tracks/java-fundamentals → :3000/tracks/java-fundamentals

步骤 3:本机 curl 对照(有 upstream 时)

先确认 Java 直连:

curl -sS -o /dev/null -w "%{http_code}" http://127.0.0.1:8080/tracks

再经 Nginx(域名按你的 test 配置):

curl -sS -o /dev/null -w "%{http_code}" https://test.example/api/tracks
# 或 http 实验环境

应看到:两者业务结果一致(路径已正确剥离)。若直连 200、经 Nginx 404,优先查 尾斜杠与 location 前缀。

步骤 4:必备头 — 逐项人话

proxy_set_header Host $host;                 # 上游看见的是公网域名,不是 127.0.0.1
proxy_set_header X-Real-IP $remote_addr;     # 单跳真实客户端 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 链式追加
proxy_set_header X-Forwarded-Proto $scheme;  # https,供后端生成正确绝对 URL / cookie Secure

Spring Boot 需信任转发头(server.forward-headers-strategy 等,见安全课),否则 redirect、限流、日志会偏。

步骤 5:WebSocket / HMR

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

本地 npm run dev 经 Nginx 时,缺这两项常见症状:热更新断开、WS 101 失败。生产静态构建的 Next 对 HMR 依赖低,但保留无害,且利于未来实时能力。

步骤 6:超时与上传体积

client_max_body_size 20m;     # 与课程封面等上传对齐;过小 → 413
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;      # 上游慢/长请求时避免过早 504

与 spring.servlet.multipart 上限一起看,两边都要够。

讲清楚要点

  1. 因为 Spring 的映射通常不含网关前缀 /api,所以 location /api/ 配 proxy_pass …/; 剥离前缀——前后端契约一致。
  2. 因为 Next 路由依赖完整路径,所以页面 location 用无尾 / 的 proxy_pass——避免误改 URI。
  3. 因为上游默认只看见代理连接,所以必须补 X-Forwarded-* 与 Host——协议、域名、IP 才正确。
  4. 因为 HTTP/1.1 升级协议需要协商,所以 WebSocket 要传 Upgrade/Connection——否则长连接建不起来。
  5. 因为上传受 Nginx 与应用双重限制,所以 client_max_body_size 要与 Spring multipart 对齐——只改一边仍会失败。
  6. 因为 502/504 常来自上游挂了或超时,所以排错先看 error.log 与上游是否 listen——不要只改浏览器。
  7. 因为官方对 proxy_pass URI 替换规则严格,所以改路径时先推演再 reload——用 curl 验证比猜快。

你可能会懵的地方

  • 为什么有人写 proxy_pass http://127.0.0.1:8080/; 不用 upstream 名?
    可以。upstream 的好处是:多实例、keepalive、换 IP 只改一处。本站生产用命名 upstream。

  • X-Forwarded-For 能信任吗?
    只信任你管控的上一跳写入的值。若前面还有 CDN,要用 real_ip 模块声明可信源,否则客户端可伪造(见安全头课)。

  • proxy_pass 末尾多一个空格或少斜杠?
    语法可能仍过 -t,但运行路径全错。改完用同一条 curl 回归。

  • Connection 写成空字符串又是什么?
    给 keepalive 复用上游连接时,常 proxy_set_header Connection "";(缓存/性能课)。与 WebSocket 的 "upgrade" 场景不同,不要混用错 location。

错法对照

错法问题正解
/api/ + proxy_pass http://backend;(无尾 /)上游收到 /api/tracks,Spring 404使用 http://backend/; 剥离
/ + proxy_pass http://platform/;(多尾 /)路径被错误改写页面用无 URI 的 proxy_pass
不设 X-Forwarded-Proto后端以为 http,redirect/cookie 错设置 $scheme
无 Upgrade 头经 Nginx 跑 next devHMR/WS 失败补 Upgrade + Connection
client_max_body_size 默认 1m上传 413提到与业务一致(如 20m)

自测三问

  1. /api/tracks 经本站生产写法后,Spring 收到的路径是什么?
  2. 列出至少三个应 proxy_set_header 的头及目的。
  3. WebSocket 场景下,Connection 头通常设成什么?

小结一句话

proxy_pass 尾斜杠决定路径如何改写;配齐转发头与 Upgrade,后端才能像「直连公网」一样正确工作。

官方延伸

  • ngx_http_proxy_module
  • proxy_pass
加载本节练习…
← 上一课静态资源下一课 →双 upstream 架构