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_cache、expires、keepalive upstream。

30 分钟

缓存与性能

这一课你将能做到

  1. 解释 upstream keepalive 为何要搭配 proxy_http_version 1.1 与清空 Connection,并对照 prod.conf.example
  2. 设计一处 只读 GET 的 proxy_cache 示例,并列出至少三个 禁止缓存 的 API 路径类型
  3. 为 Next 的 /_next/static/ 与 HTML 文档写出不同的 expires / Cache-Control 策略

为什么要学

反代正确只是「能用」;生产还要「扛得住」。最便宜的两刀是:复用到上游的连接(keepalive) 与 对可缓存响应做边缘缓存。
CodeRoadMap 已在 upstream 打开 keepalive;proxy_cache 则是可选加速,且极易误伤登录态与写操作。
业务层还有 Redis 缓存(redis-essentials)——Nginx 缓存是更外层。本课把分层与「什么绝对不能缓存」讲清。

先建立图像

浏览器缓存 (expires / Cache-Control)
        │
        ▼
Nginx proxy_cache(可选,按 URI/状态码)
        │
        ▼
upstream keepalive 池 ──► Spring / Next
        │
        ▼
应用内缓存(Redis 等)──► MySQL

人话:越靠外的缓存越要「傻而安全」——只缓存公开、幂等、可过期的;越靠内越懂业务失效。

手段作用本站现状
upstream keepalive少握手prod 已开
expires / Cache-Control控浏览器按资源类型配
proxy_cache缓存上游响应可选实验
Redis业务热点应用层开关

跟着做

步骤 1:读懂已有 keepalive

upstream coderoadmap_backend {
    server 127.0.0.1:8080;
    keepalive 64;
}

location /api/ {
    proxy_pass http://coderoadmap_backend/;
    proxy_http_version 1.1;
    # 清空 Connection,才能复用上游 keep-alive
    proxy_set_header Connection "";
    # … 其他 proxy_set_header …
}

注意:这与 WebSocket location 里 Connection "upgrade" 不同。页面反代若要同时支持 HMR,需按 location 分开策略,或接受「开发走直连、生产关 HMR」。

步骤 2:规划 proxy_cache(实验向)

# 放在 http 块
proxy_cache_path /var/cache/nginx/api
    levels=1:2
    keys_zone=api_cache:10m
    max_size=100m
    inactive=10m;

# 仅示意:公开列表可短缓存
location = /api/tracks {
    proxy_cache api_cache;
    proxy_cache_valid 200 60s;
    proxy_cache_key "$scheme$request_method$host$request_uri";
    add_header X-Cache-Status $upstream_cache_status always;

    proxy_pass http://coderoadmap_backend/tracks;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_set_header Host $host;
}

用 curl -I 连续两次,观察 X-Cache-Status:MISS → HIT(若配置生效)。

步骤 3:列出禁止缓存清单

在笔记写死:

  1. /api/auth/* — 登录态、令牌
  2. 一切非 GET(POST/PUT/DELETE)
  3. 带用户私有数据的响应(进度、个人信息)
  4. 管理端写操作与 CSRF 相关接口

对应配置思维:proxy_cache off; 或根本不把这些 location 放进 cache 区。

步骤 4:Next 静态长缓存

location /_next/static/ {
    proxy_pass http://coderoadmap_platform;
    expires 365d;
    add_header Cache-Control "public, immutable";
}

构建产物带 content hash,长缓存安全。HTML 文档保持短 TTL 或 no-cache,避免壳不更新。

步骤 5:通用 I/O 小开关

sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;   # 细节见静态课

与容器 CPU limit 一起看:压缩与 TLS 都吃 CPU,需给 Nginx worker 留余量。

步骤 6:分层对照 Redis

打开脑内对照:

  • Nginx:按 URL 的傻缓存,失效靠 TTL
  • Redis:按业务 key,可主动删除(Cache-Aside)

公开 tracks 列表两者都能做;不要双层无限叠长 TTL 还不失效,否则发版内容陈旧。

实践建议:若已在 Spring/Redis 做列表缓存,Nginx proxy_cache 可先不开;等公开只读流量成为明确瓶颈,再对单一 GET location 试点 30~60 秒 TTL,并用 X-Cache-Status 证明收益后,才考虑扩大范围。

讲清楚要点

  1. 因为每次新建 TCP/HTTP 有成本,所以 upstream keepalive 能降低高 QPS 握手——需 HTTP/1.1 与正确 Connection。
  2. 因为缓存错数据比慢更可怕,所以 proxy_cache 只给公开幂等 GET——写路径与鉴权路径关闭。
  3. 因为浏览器也有缓存,所以 expires 与 proxy_cache 是不同层——改配置要想「谁在缓存」。
  4. 因为 hash 静态可变,所以 /_next/static/ 可 immutable 长缓存——HTML 不能同等对待。
  5. 因为 Redis 更懂业务失效,所以边缘缓存 TTL 宜短或可关——出问题先关 Nginx 缓存保正确。
  6. 因为 X-Cache-Status 可观测,所以实验时务必打头——否则不知道有没有打中。
  7. 因为官方 proxy_cache 指令多,所以先小范围 location 试点再扩大——忌全局一刀切。

你可能会懵的地方

  • keepalive 与 worker_connections 什么关系?
    worker 要能扛「客户端连接 + 上游连接」。keepalive 占上游侧槽位;调大前看系统与 worker_connections。

  • 缓存了带 Set-Cookie 的响应怎么办?
    危险。确保不缓存个性化响应;必要时用 proxy_no_cache / proxy_cache_bypass 按 cookie 判断。

  • 为什么生产示例没开 proxy_cache?
    正确性优先;列表可走 Redis。Nginx 缓存是可选优化,不是本站默认必需。

  • HIT 了但内容旧?
    缩短 proxy_cache_valid,或发版时清理 cache 目录,或改 cache key 版本前缀。

错法对照

错法问题正解
缓存 POST / 登录响应串会话、泄密仅公开 GET;auth 关闭
WebSocket location 清空 Connection升级失败upgrade 与 keepalive 分 location
HTML 也 365d immutable用户卡旧壳文档短缓存
无限加长 TTL 不观测陈旧难查加 X-Cache-Status,TTL 保守
以为 gzip 能替代缓存每次仍打上游压缩 ≠ 缓存

自测三问

  1. keepalive 生效通常需要哪两个搭配条件?
  2. 举三个不应被 Nginx proxy_cache 的路径或条件。
  3. /_next/static/ 与 HTML 的缓存策略为何不同?

小结一句话

keepalive 生产已开;proxy_cache 只给公开只读 GET;静态长缓存、HTML 短缓存,并与 Redis 分层。

官方延伸

  • ngx_http_proxy_module — proxy_cache
  • ngx_http_upstream_module — keepalive
加载本节练习…
← 上一课安全响应头下一课 →负载均衡