Web服务器之Nginx综合详解
Web服务器之Nginx综合详解引言一、nginx 是什么二、nginx 的核心工作流程三、nginx 的基础概念四、nginx 的典型使用场景五、nginx 配置的基本结构六、零基础如何理解 nginx七、root、alias、rewrite 的搭配关系八、进阶理解nginx 的规则优先级九、常见高级指令与用途十、实际项目中怎么组合十一、零基础学习 nginx 的正确顺序十二、最容易踩坑的地方十三、一个完整综合示例十四、总结拓展证书配置与缓存处理深度解析一、HTTPS 与证书是什么二、HTTPS 工作流程零基础理解三、证书文件是什么四、nginx 配置 HTTPS五、HTTPS 配置详解六、HTTP 自动跳 HTTPS七、完整 HTTPS 配置生产环境八、HTTPS 中的重要优化九、什么是缓存十、缓存有哪些层级十一、静态资源缓存十二、expires十三、缓存控制 Header十四、为什么前端喜欢 hash 文件名十五、推荐的静态缓存方案十六、HTML 为什么不能长期缓存十七、前端缓存最佳实践十八、gzip 压缩十九、代理缓存高级二十、适合缓存的接口二十一、反向代理综合方案二十二、真实项目中的 nginx 分工二十三、nginx 学习路线推荐二十四、最容易踩的 HTTPS 坑二十五、最容易踩的缓存坑二十六、一句话总结 nginxnginx 解决缓存问题前端缓存 / 浏览器缓存 / nginx 缓存一、为什么会有缓存问题二、缓存问题最常见的场景三、缓存的层级四、前端缓存最佳实践核心五、为什么 HTML 不建议缓存六、为什么 JS/CSS 适合长期缓存七、正确 nginx 缓存配置最重要八、静态资源长期缓存推荐九、为什么这样不会有缓存问题十、Vue / React / Vite 默认已经支持 hash十一、最容易犯的错误十二、推荐生产方案标准十三、Vue / React SPA 完整推荐配置十四、如何强制浏览器更新十五、接口缓存问题十六、nginx 代理缓存高级十七、哪些接口适合缓存十八、缓存控制最核心 Header十九、304 是什么二十、缓存问题排查方法二十一、最推荐的现代缓存策略二十二、真正现代前端缓存体系二十三、完整生产级推荐配置二十四、一句话总结缓存问题引言nginx 是一个高性能的 Web 服务器、反向代理服务器、负载均衡器和静态资源服务器。它最常见的用途不是“单纯发网页”而是站在前端与后端之间负责静态资源分发、请求转发、协议终止、缓存、访问控制等工作。如果把一个网站系统看成一条流水线那么 nginx 常常处在最前面负责接收请求、判断请求该去哪里、把请求交给静态文件或后端服务、再把结果返回给客户端。一、nginx 是什么nginx 的核心能力可以概括成四件事接收请求匹配规则做路径映射、改写或转发返回结果它不是一个“只会开网页”的工具而是一个非常强的请求调度层。常见身份有四种Web 服务器直接返回 HTML、CSS、JS、图片、下载文件反向代理把请求转发给后端应用负载均衡器把请求分配给多个后端实例网关入口统一处理 HTTPS、跨域、限流、鉴权、缓存等二、nginx 的核心工作流程一个请求进入 nginx 后通常会经历下面的过程客户端请求→ 选择 server → 选择 location → 判断是否 rewrite → 决定 root /alias/ proxy_pass /return→ 可能执行 try_files → 返回静态文件或转发后端这条流程非常重要。很多 nginx 配置看起来复杂本质上都是在这条链路上做控制。三、nginx 的基础概念1. serverserver 表示一个虚拟主机。一个 nginx 可以配置多个 server用来承载多个域名、多个站点、多个项目。例如server { listen 80; server_name example.com; }意思是当请求的域名是 example.com并且端口是 80 时走这个 server。2. locationlocation 是 nginx 的核心之一用来匹配请求 URI。例如location /api/ { }表示凡是以 /api/ 开头的请求都进入这个规则。location 决定“这个请求走哪一段逻辑”。3. rootroot 是把 URI 直接拼接到目录后面。例如location / { root /var/www/site; }请求 /index.html 时实际会找/var/www/site/index.html如果请求 /assets/a.js则找/var/www/site/assets/a.js它适合“目录结构和 URL 结构比较一致”的场景。4. aliasalias 是把 location 匹配到的路径前缀替换成另一个目录。例如location /images/ { alias /data/pic/; }请求 /images/a.png 时对应磁盘路径是/data/pic/a.png它适合“URL 前缀和磁盘目录不一致”的场景。5. rewriterewrite 是修改 URI 的规则不是文件映射。例如rewrite ^/old/(.*)$ /new/$1 permanent;表示把旧地址永久跳转到新地址。它常用于老地址迁移URL 规范化去掉前缀加前缀强制跳转到 HTTPS6. try_filestry_files 是 nginx 中非常实用的指令作用是按顺序检查文件是否存在。例如location / { root /var/www/app; try_files $uri $uri/ /index.html; }意思是先找真实文件再找目录都没有就返回 /index.html这是前端单页应用最常见的写法。7. proxy_passproxy_pass 用于反向代理把请求转发给后端服务例如location /api/ { proxy_pass http://127.0.0.1:3000; }表示 /api/ 下的请求都交给本地 3000 端口的后端程序。四、nginx 的典型使用场景1. 静态网站托管适合 HTML、CSS、JS、图片、下载文件等。server { listen 80; server_name example.com; root /var/www/site; index index.html; }适合公司官网博客文档站活动页资源下载站2. 单页应用 SPAVue、React、Angular 打包后前端路由都需要 nginx 配合。location / { root /var/www/dist; try_files $uri $uri/ /index.html; }作用直接访问 /home刷新 /home跳转到 /user/list都不会 404而是交给前端路由处理。3. 反向代理后端接口前端页面和后端接口通常分离。location /api/ { proxy_pass http://127.0.0.1:3000; }适合Node.jsNestJSJava Spring BootGoPythonPHP-FPM4. 静态资源独立托管图片、上传文件、音视频、PDF 等往往单独放目录。location /upload/ { alias /data/upload/; }适合用户头像文件下载上传图片大文件存储5. HTTPS 统一入口nginx 常负责证书和 TLS 终止。server { listen 443 ssl; server_name example.com; ssl_certificate /path/fullchain.pem; ssl_certificate_key /path/privkey.pem; }这样后端就不用自己处理证书。6. 域名跳转、路径跳转return 301 https://$host$request_uri;常用于HTTP 自动跳 HTTPS老域名跳新域名旧路径跳新路径7. 负载均衡多个后端实例时nginx 可以分流。upstream backend { server 127.0.0.1:3000; server 127.0.0.1:3001; } server { location / { proxy_pass http://backend; } }五、nginx 配置的基本结构一个完整配置通常包括worker_processes auto; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; server { listen 80; server_name example.com; location / { root /var/www/site; index index.html; } } }理解顺序events网络事件模型httpHTTP 服务配置server站点级配置location路径级配置六、零基础如何理解 nginx你可以把 nginx 想成一个“规则分发器”。它先看你访问的是哪个域名你访问的是哪个路径这个路径是静态文件还是接口如果是文件去磁盘找如果是接口转发给后端如果地址要改先 rewrite如果找不到给出 404 或 fallback所以 nginx 的本质不是“写网页”而是“决定请求该怎么走”。七、root、alias、rewrite 的搭配关系这三者是 nginx 路径处理的核心组合。1. root try_files适合静态站点和 SPA。location / { root /var/www/app; try_files $uri $uri/ /index.html; }这是最常用组合之一。2. alias try_files适合独立目录映射。location /files/ { alias /data/storage/files/; try_files $uri 404; }3. rewrite root适合先改地址再按目录取文件。rewrite ^/v1/(.*)$ /$1 last; location / { root /var/www/site; }4. rewrite proxy_pass适合旧接口转新接口或统一 API 路由。location /old-api/ { rewrite ^/old-api/(.*)$ /api/$1 break; proxy_pass http://127.0.0.1:3000; }5. location alias适合资源目录映射。location /images/ { alias /data/images/; }这是最清楚的写法之一。八、进阶理解nginx 的规则优先级nginx 的配置不是“从上到下随便走”而是有优先级的。大致顺序可以理解为精确匹配 前缀匹配 ^~正则匹配 ~ / ~*普通前缀匹配例如location /login { }精确匹配最高。九、常见高级指令与用途1. return用于直接返回状态码或跳转。return 301 https://example.com$request_uri;通常比 rewrite 更简单、更清晰。2. index定义默认首页。location / { root /var/www/site; index index.html index.htm; }3. error_page自定义错误页。error_page 404 /404.html;4. gzip压缩响应内容减少传输体积。gzip on;适合静态资源和文本内容。5. expires设置缓存时间。location /static/ { expires 30d; }适合版本固定的静态文件。6. deny / allow控制访问权限。location /admin/ { deny all; }或者做 IP 白名单。7. upstream管理后端服务组。upstream app_server { server 127.0.0.1:3000; server 127.0.0.1:3001; }常用于负载均衡。十、实际项目中怎么组合方案一前端 后端分离server { listen 80; server_name example.com; location / { root /var/www/front; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:3000; } }适合Vue NestJSReact Spring Boot任意前后端分离项目方案二静态资源独立目录server { listen 80; server_name example.com; location /static/ { alias /data/static/; expires 30d; } }适合图片、CSS、JS、下载文件。方案三HTTPS 强制跳转server { listen 80; server_name example.com; return 301 https://$host$request_uri; }方案四旧路径兼容rewrite ^/old/(.*)$ /new/$1 permanent;适合站点改版后保留旧链接。十一、零基础学习 nginx 的正确顺序建议按这个顺序学第一步先理解 server 和 location知道请求是怎么被分发的。第二步学会 root 和 alias理解文件路径怎么映射。第三步学会 try_files解决 404 和 SPA 刷新问题。第四步学会 proxy_pass把前端和后端接起来。第五步学会 rewrite 和 return处理跳转和路径规范化。第六步再学 upstream、缓存、压缩、访问控制进入进阶使用。十二、最容易踩坑的地方1. root 和 alias 混用错误root 是拼接alias 是替换。两者不是一回事。2. SPA 刷新 404原因通常是没有 try_files $uri $uri/ /index.html;。3. rewrite 导致循环特别是 last 使用不当时会反复重写。4. proxy_pass 路径拼接问题location 和 proxy_pass 末尾斜杠不同会影响路径结果。这是 nginx 里非常经典的坑。5. alias 末尾斜杠问题alias 的路径写法要非常注意尤其是 location /xxx/ 和 alias /path/ 的配合。十三、一个完整综合示例server { listen 80; server_name example.com; # 强制跳转 HTTPS return 301 https://$host$request_uri; } server { listen 443 ssl; server_name example.com; ssl_certificate /path/fullchain.pem; ssl_certificate_key /path/privkey.pem; # 前端页面 location / { root /var/www/front; try_files $uri $uri/ /index.html; } # 后端接口 location /api/ { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # 静态图片 location /images/ { alias /data/images/; expires 30d; } # 旧地址跳转 location /old/ { rewrite ^/old/(.*)$ /new/$1 permanent; } }这个配置基本把 nginx 的常见能力都串起来了HTTPS静态页面接口代理图片目录旧链接跳转十四、总结nginx 不是单纯的“网页服务器”而是一个请求调度中心。它最重要的能力就是location匹配请求rewrite / return修改请求或跳转root / alias映射文件路径try_files判断文件是否存在proxy_pass转发到后端如果只记住一句话nginx 的核心就是根据 URI 决定这个请求是改、找、转、还是回。拓展证书配置与缓存处理深度解析现代 nginx 项目里真正最核心的两部分通常是1. HTTPS 证书 2. 缓存控制因为HTTPS 决定网站安全缓存决定网站性能几乎所有生产环境 nginx 配置最终都会围绕静态资源 HTTPS 缓存 反向代理这四大体系展开。一、HTTPS 与证书是什么HTTPS 本质上HTTP SSL/TLS作用数据加密防止中间人攻击身份认证浏览器安全信任如果没有 HTTPS用户名 密码 Token Cookie都可能被抓包。所以现代网站基本必须 HTTPS。二、HTTPS 工作流程零基础理解浏览器访问https://example.com时浏览器 ↓ 向服务器请求证书 ↓ 服务器返回 SSL 证书 ↓ 浏览器验证证书是否合法 ↓ 建立加密连接 ↓ 开始 HTTPS 通信nginx 通常负责TLS 握手 证书加载 加密通信后端程序NestJS Node Java Go通常只处理普通 HTTP。这就是nginx HTTPS 终止三、证书文件是什么最常见的是文件作用.pem公钥证书.key私钥.crt证书.csr证书申请文件现代 nginx 最常见fullchain.pem privkey.pem四、nginx 配置 HTTPS最基础配置server { listen 443 ssl; server_name example.com; ssl_certificate /ssl/fullchain.pem; ssl_certificate_key /ssl/privkey.pem; location / { root /www/site; index index.html; } }五、HTTPS 配置详解1. listen 443 ssl表示监听 443 HTTPS 端口 启用 SSL2. ssl_certificate指定证书文件。ssl_certificate /ssl/fullchain.pem;里面包含网站公钥 证书链 CA 信息3. ssl_certificate_key指定私钥。ssl_certificate_key /ssl/privkey.pem;这是最重要文件。绝对不能泄露。六、HTTP 自动跳 HTTPS生产环境基本都会这样server { listen 80; server_name example.com; return 301 https://$host$request_uri; }作用HTTP 自动永久跳转 HTTPS例如http://example.com/user ↓ https://example.com/user七、完整 HTTPS 配置生产环境server { listen 80; server_name example.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name example.com; ssl_certificate /ssl/fullchain.pem; ssl_certificate_key /ssl/privkey.pem; ssl_session_timeout 10m; ssl_session_cache shared:SSL:10m; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; location / { root /www/site; try_files $uri $uri/ /index.html; } }八、HTTPS 中的重要优化1. HTTP/2listen 443 ssl http2;作用多路复用更快加载减少阻塞现代网站建议开启。2. TLS 版本ssl_protocols TLSv1.2 TLSv1.3;建议禁用 TLS1.0 / TLS1.1因为已经不安全。3. Session 缓存ssl_session_cache shared:SSL:10m;作用减少重复握手 提高 HTTPS 性能九、什么是缓存缓存的本质不要重复请求缓存能极大减少网络传输服务器压力页面加载时间缓存是 nginx 最重要能力之一。十、缓存有哪些层级浏览器访问网页时浏览器缓存 ↓ CDN 缓存 ↓ nginx 缓存 ↓ 后端缓存 ↓ 数据库缓存nginx 主要负责静态资源缓存 代理缓存十一、静态资源缓存这是最常见缓存。例如JSCSS图片字体视频这些文件通常不会频繁变化。十二、expires最经典缓存指令。location /static/ { expires 30d; }意思缓存 30 天浏览器30 天内不再请求服务器十三、缓存控制 Headernginx 会自动生成Cache-Control Expires例如Cache-Control: max-age2592000十四、为什么前端喜欢 hash 文件名例如app.9a8d7c.js原因文件变了 hash 就变 浏览器自动重新请求所以静态资源可以长期缓存这就是现代前端缓存体系。十五、推荐的静态缓存方案location /static/ { root /www/front; expires 30d; add_header Cache-Control public; }适合VueReactViteWebpack十六、HTML 为什么不能长期缓存HTML 通常经常变化如果缓存太久用户看到旧页面所以location / { add_header Cache-Control no-cache; }十七、前端缓存最佳实践现代前端通常类型缓存策略HTML不长期缓存JS/CSS长缓存图片长缓存API视业务而定十八、gzip 压缩缓存之外压缩也非常重要。开启 gzipgzip on;推荐配置gzip on; gzip_comp_level 5; gzip_min_length 1k; gzip_types text/plain text/css application/javascript application/json;作用例如500KB JS ↓ 100KB加载速度大幅提升。十九、代理缓存高级nginx 不仅能缓存静态文件。还能缓存后端接口响应这叫proxy_cache基础代理缓存proxy_cache_path /data/cache levels1:2 keys_zonemy_cache:10m max_size1g;使用缓存location /api/ { proxy_cache my_cache; proxy_pass http://127.0.0.1:3000; }作用第一次请求后端 后续直接返回缓存二十、适合缓存的接口适合新闻商品列表首页公共配置不适合用户信息支付登录状态二十一、反向代理综合方案现代 nginx 最典型server { listen 443 ssl http2; server_name example.com; ssl_certificate /ssl/fullchain.pem; ssl_certificate_key /ssl/privkey.pem; gzip on; # 前端页面 location / { root /www/front; try_files $uri $uri/ /index.html; add_header Cache-Control no-cache; } # 静态资源 location /static/ { root /www/front; expires 30d; add_header Cache-Control public; } # 接口 location /api/ { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # 图片 location /upload/ { alias /data/upload/; expires 7d; } }二十二、真实项目中的 nginx 分工nginx 通常负责功能是否适合 nginxHTTPS非常适合静态资源非常适合缓存非常适合图片下载非常适合反向代理非常适合负载均衡非常适合WebSocket适合API 业务逻辑不适合二十三、nginx 学习路线推荐初级先学serverlocationrootaliastry_files中级再学proxy_passrewritereturnHTTPS高级最后学upstream缓存gzip限流WebSocketLua/OpenResty二十四、最容易踩的 HTTPS 坑1. 证书路径错误找不到 pem/key2. 私钥不匹配pem 和 key 不是一对3. 没开放 443云服务器安全组经常忘记。4. HTTP 和 HTTPS 混用会出现Mixed Content二十五、最容易踩的缓存坑1. HTML 被缓存导致页面更新后用户还是旧版本。2. JS 缓存失效解决方案hash 文件名3. 接口缓存错误用户数据被缓存给别人。这是严重问题。二十六、一句话总结 nginxnginx 的核心本质根据 URI 和规则 决定请求该如何处理而现代生产环境 nginx 的核心能力HTTPS 缓存 静态资源 反向代理 负载均衡这几乎就是所有互联网项目的基础入口层。nginx 解决缓存问题前端缓存 / 浏览器缓存 / nginx 缓存缓存问题是前端和 nginx 中最常见的问题之一。典型现象页面更新了 用户还是旧页面或者CSS 改了没生效 JS 更新了浏览器不加载再或者接口返回旧数据这些本质上都是缓存没有正确失效一、为什么会有缓存问题浏览器为了提高速度会缓存HTMLJSCSS图片接口数据这样下次访问直接本地读取 不用重新请求性能更高。但问题是资源更新后 浏览器可能继续使用旧缓存这就是缓存问题。二、缓存问题最常见的场景1. HTML 更新不生效例如index.html 修改了 用户还是旧页面这是最危险的问题。2. JS/CSS 更新不生效例如app.js 更新了 浏览器继续使用旧 JS导致页面异常接口错误功能失效3. 图片缓存例如logo 改了 用户看到旧 logo4. nginx 代理缓存例如接口返回旧数据三、缓存的层级一个请求可能经过浏览器缓存 ↓ Service Worker ↓ CDN 缓存 ↓ nginx 缓存 ↓ 后端缓存所以缓存问题不一定是 nginx四、前端缓存最佳实践核心现代前端真正标准方案文件类型缓存策略HTML不缓存JS/CSS长缓存图片长缓存API视情况五、为什么 HTML 不建议缓存HTML 是入口文件。例如index.html它里面引用scriptsrc/static/app.a1b2c3.js/script如果 HTML 被缓存用户永远拿不到新 JS所以HTML 必须尽量不缓存六、为什么 JS/CSS 适合长期缓存现代前端会生成app.8a9d7c.js style.a8c9d1.css这种hash 文件名机制。文件内容变hash 就变于是浏览器自动重新请求这才是现代缓存体系核心。七、正确 nginx 缓存配置最重要HTML 不缓存推荐location / { root /www/front; try_files $uri $uri/ /index.html; add_header Cache-Control no-cache, no-store, must-revalidate; add_header Pragma no-cache; add_header Expires 0; }Cache-Control核心缓存头。no-cache表示使用缓存前必须重新验证no-store表示完全不允许缓存must-revalidate表示缓存失效后必须重新请求Pragma兼容老浏览器。Expires 0立即过期。八、静态资源长期缓存推荐JS/CSS/图片缓存location /static/ { root /www/front; expires 30d; add_header Cache-Control public; }九、为什么这样不会有缓存问题因为JS 文件名带 hash例如app.abc123.js更新后app.xyz888.js浏览器认为这是新文件于是自动重新下载。十、Vue / React / Vite 默认已经支持 hash例如dist/assets/index-8d9a7c.js这就是缓存优化十一、最容易犯的错误错误一HTML 长缓存例如expires 30d;如果加到/上。会导致index.html 被缓存用户更新不了。错误二所有文件都 no-cache这样虽然不会缓存错误。但性能极差因为JSCSS图片每次都重新下载。十二、推荐生产方案标准HTML 不缓存location / { try_files $uri $uri/ /index.html; add_header Cache-Control no-cache; }静态资源长缓存location /assets/ { expires 30d; add_header Cache-Control public; }十三、Vue / React SPA 完整推荐配置server { listen 80; server_name example.com; root /www/front; # HTML location / { try_files $uri $uri/ /index.html; add_header Cache-Control no-cache; } # 静态资源 location /assets/ { expires 30d; add_header Cache-Control public; } }这是现代 SPA 最经典配置。十四、如何强制浏览器更新方法一Ctrl F5强制刷新。方法二改文件 hash推荐真正标准方案。方法三修改 URL 参数例如app.js?v2但已经逐渐淘汰现代前端更推荐hash 文件名十五、接口缓存问题禁止接口缓存location /api/ { proxy_pass http://127.0.0.1:3000; add_header Cache-Control no-store; }适合用户信息登录状态实时数据十六、nginx 代理缓存高级nginx 可以缓存接口。开启缓存proxy_cache_path /data/cache levels1:2 keys_zonemy_cache:10m max_size1g;使用缓存location /api/ { proxy_cache my_cache; proxy_cache_valid 200 10m; proxy_pass http://127.0.0.1:3000; }含义200 响应缓存 10 分钟十七、哪些接口适合缓存适合新闻列表首页商品列表配置接口不适合用户数据Token支付登录十八、缓存控制最核心 HeaderCache-Control最重要。例如Cache-Control: no-cacheExpiresHTTP1.0 老机制。ETag资源唯一标识。浏览器文件没变 直接返回 304Last-Modified最后修改时间。十九、304 是什么很多人误以为304 没请求服务器其实请求了 但服务器告诉浏览器文件没变所以继续使用缓存二十、缓存问题排查方法Chrome F12打开Network查看StatusCache-ControlExpiresETagDisable cache开发时可勾选Disable cache二十一、最推荐的现代缓存策略HTMLno-cacheJS/CSShash 长缓存图片长缓存API按业务决定二十二、真正现代前端缓存体系现代项目真正核心HTML 永远最新 JS/CSS 永远 hash这是Vue React Vite Webpack默认就在做的事情。二十三、完整生产级推荐配置server { listen 80; server_name example.com; root /www/front; # HTML location / { try_files $uri $uri/ /index.html; add_header Cache-Control no-cache, no-store, must-revalidate; expires -1; } # 静态资源 location /assets/ { expires 30d; add_header Cache-Control public; } # 图片 location /images/ { expires 7d; } # 接口 location /api/ { proxy_pass http://127.0.0.1:3000; add_header Cache-Control no-store; } }二十四、一句话总结缓存问题缓存问题真正核心不要缓存 HTML 长期缓存带 hash 的静态资源这是现代 Web 最标准方案。