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

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

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

学习

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

更多

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

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Nginx 反向代理入门/课时/双 upstream 架构
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综合练习

双 upstream 架构

/api 到 Spring Boot、/ 到 Next.js,对照 prod.conf。

35 分钟

双 upstream 架构

这一课你将能做到

  1. 读懂并口述 CodeRoadMap「双 upstream」:coderoadmap_backend 与 coderoadmap_platform 的端口与职责
  2. 对照 prod.conf.example,把浏览器 URL 映射到「哪个进程、改写后哪条路径」
  3. 说明本地直连、Docker 服务名、单机 127.0.0.1 三种写法如何替换 upstream,而不改前端 /api 前缀

为什么要学

单看 proxy_pass 还不够:生产是 两个命名上游 + 多个 server(www / 裸域跳转 / admin) 的拓扑。
platform 用相对路径 /api 调后端,靠 同源 避开 CORS;同源成立的前提就是 Nginx 把两个进程合成一个对外站点。
本课把拓扑、请求表、与 Docker/本机差异一次对齐,SSL 与安全头是在此骨架上长出来的叶子。

先建立图像

https://www.coderoadmap.cn
              │
         ┌────┴────┐
         │  Nginx  │  :443 TLS
         └────┬────┘
              │
     ┌────────┴────────┐
     │                 │
 /api/*              其他
     │                 │
     ▼                 ▼
upstream             upstream
backend:8080         platform:3000
Spring Boot          Next.js
     │
     └──► MySQL / Redis …
浏览器 URL命中 location上游上游 URI
/tracks/nginx-essentials/:3000同左
/api/tracks/api/:8080/tracks
/api/auth/login/api/:8080/auth/login
admin 的 /index.htmladmin /磁盘 root—
admin 的 /api/...admin /api/:8080剥前缀

人话:对外一个域名,对内两栋楼;门岗按「路径工牌」分楼。

跟着做

步骤 1:朗读两段 upstream

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

upstream coderoadmap_platform {
    server 127.0.0.1:3000;
    keepalive 64;          # 复用到 Next 的连接
}

upstream coderoadmap_backend {
    server 127.0.0.1:8080;
    keepalive 64;          # 复用到 Spring 的连接
}

笔记:「名字是给 location 用的逻辑名;IP/端口可随环境替换。」

步骤 2:对照 www 主 server

server {
    listen 443 ssl http2;
    server_name www.coderoadmap.cn;
    client_max_body_size 20m;
    # add_header … 见安全头课

    location /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 / {
        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;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

口头走查:GET /tracks/redis-essentials 从 Nginx 到 MySQL 的链路(页面在 Next,数据经浏览器再打 /api/... 或服务端 fetch)。

步骤 3:理解「同源 /api」

platform 侧 API 客户端通常以 /api 为前缀(如 platform/src/lib/api.ts 一类封装)。浏览器只看见 www 一个源:

  • 无浏览器 CORS 预检烦恼(同站)
  • Cookie / 凭证策略更简单
  • 换机器部署时,前端不必写死 http://ip:8080

应看到:双 upstream 是产品体验与安全边界的共同选择。

步骤 4:域名与跳转块

同文件中还有:

  • listen 80:http → https://www…$request_uri
  • server_name coderoadmap.cn 的 443:裸域 → www

统一 canonical,避免 cookie 域与 SEO 分裂。细节加强在 SSL 课。

步骤 5:Docker 网络替换演练(笔记)

Compose 内 Nginx 与应用同网时,upstream 常改为:

upstream coderoadmap_backend {
    server backend:8080;   # 服务名,非 127.0.0.1
    keepalive 64;
}
upstream coderoadmap_platform {
    server platform:3000;
    keepalive 64;
}

宿主机 Nginx + 容器映射端口时,则仍可能是 127.0.0.1:宿主映射端口。
关键:改 upstream,不改浏览器路径约定。

步骤 6:若删掉 /api/ 会怎样

思考题写进笔记:

  • 请求 /api/tracks 落入 location / → Next
  • Next 无此 API 路由 → 404 或 HTML
  • Spring 完全收不到

结论:/api/ location 不是装饰,是分流开关。

讲清楚要点

  1. 因为页面与 API 分属不同运行时,所以用两个 upstream 而不是一个万能端口——职责清晰、可独立扩缩。
  2. 因为要对浏览器保持同源,所以对外只暴露 Nginx 域名,路径内分流——前端继续用 /api。
  3. 因为 admin 也要调同一套 REST,所以 admin server 复用 coderoadmap_backend——静态壳 + 同一 Java。
  4. 因为 keepalive 在 upstream 声明,所以高 QPS 下减少对 8080/3000 的握手——配合 proxy_http_version 1.1。
  5. 因为环境不同(本机/Compose/K8s),所以变的是 server 地址,不是 location 语义——配置可移植。
  6. 因为 80/裸域跳转与主站分离成多个 server,所以改证书或跳转不影响 location 逻辑——块职责单一。
  7. 因为官方 upstream 就是为反代与负载均衡设计,所以先单实例双上游,再学多实例——下一课之后扩展。

你可能会懵的地方

  • Next 服务端组件自己请求 API,还走 Nginx 吗?
    取决于你怎么配:有的用集群内 http://backend:8080 直连;浏览器侧仍走公网 /api。两种可以并存,注意别把内网 URL 泄露到浏览器包。

  • 为什么不把 API 放到 api.coderoadmap.cn 子域?
    可以,但是 CORS 与 cookie 域要额外设计。本站选择 同域路径分流,配置与前端更简单。

  • keepalive 64 是不是越大越好?
    过大占连接与文件描述符;过小失去复用。先与官方示例同量级,再按监控调(见缓存性能课)。

  • test.conf 与 prod.conf 差在哪?
    域名、证书、跳转复杂度、keepalive 数值等;双 upstream + /api/ + / 结构一致。见 deploy/nginx/test.conf.example。

错法对照

错法问题正解
前端写死 http://127.0.0.1:8080生产跨域/错误主机浏览器只用相对 /api
upstream 写成公网 IP 且开放 8080绕过 Nginx 安全边界应用绑内网/回环
只配 platform 不配 /api/API 全 404/HTML保留剥前缀的 /api/
Compose 仍用 127.0.0.1容器内指到自己用服务名 DNS
www 与 admin 各起一套重复 Java运维翻倍共享 coderoadmap_backend

自测三问

  1. coderoadmap_backend 与 coderoadmap_platform 默认端口各是多少?
  2. 浏览器请求 /api/tracks 与 /tracks/foo 分别由谁处理?上游 URI 有何不同?
  3. 为什么说双 upstream 能减少浏览器 CORS 问题?

小结一句话

双 upstream 是 CodeRoadMap 核心拓扑:API 8080、页面 3000,同源路径分流写在 prod.conf.example。

官方延伸

  • ngx_http_upstream_module
  • ngx_http_proxy_module
加载本节练习…
← 上一课反向代理基础下一课 →HTTPS 与证书