Nginx动静分离
静态资源 (Static Content)定义:内容在服务器上预先存在,且对所有用户都相同,不会随请求而改变。典型代表.html.css.js.jpg.png.gif.ico.woff等文件。特点:读取快、可缓存、无状态。动态资源 (Dynamic Content)定义:内容需要服务器在收到请求后,通过执行程序(如查询数据库、调用 API)实时生成。典型代表.jsp.php/search?q=ng
一、引言:你的网站为什么慢?可能忽略了这一点!
你是否遇到过这样的情况:
- 网站用户一多,服务器 CPU 就飙升到 100%?
- 明明后端逻辑不复杂,但页面加载就是很慢?
- 每次用户刷新页面,都要重新下载一遍 CSS、JS 和图片?
问题的根源很可能在于——没有做动静分离。
在传统的“一体化”部署中,无论是动态生成的 HTML,还是几乎永不变化的 Logo 图片,都由同一个应用服务器(如 Tomcat、Node.js)处理。这不仅浪费了宝贵的计算资源,还增加了不必要的网络开销。
Nginx 动静分离,就是解决这个问题的终极方案。它能让 Nginx 这个“性能怪兽”直接处理所有静态文件,而将复杂的动态请求才交给后端应用。本文将带你从原理到实战,彻底掌握这项必备技能。
💡 核心价值:
学会动静分离,你的网站响应速度能提升数倍,服务器成本能降低一半!
二、什么是动静分离?
静态资源 vs. 动态资源
-
静态资源 (Static Content):
- 定义:内容在服务器上预先存在,且对所有用户都相同,不会随请求而改变。
- 典型代表:
.html,.css,.js,.jpg,.png,.gif,.ico,.woff等文件。 - 特点:读取快、可缓存、无状态。
-
动态资源 (Dynamic Content):
- 定义:内容需要服务器在收到请求后,通过执行程序(如查询数据库、调用 API)实时生成。
- 典型代表:
.jsp,.php,/api/user/profile,/search?q=nginx等。 - 特点:处理慢、消耗 CPU/内存、通常不可缓存。
动静分离的核心思想
“让专业的人做专业的事”。
- Nginx:作为高性能的 Web 服务器,极其擅长处理静态文件的读取和发送。
- 后端应用 (Tomcat/Node.js等):专注于业务逻辑和数据处理。
通过 Nginx 的 location 指令,我们可以根据请求的 URL 后缀或路径,智能地将流量分流:
- 匹配到静态资源?Nginx 直接返回文件,不打扰后端。
- 匹配到动态请求?Nginx 作为反向代理,转发给后端处理。
三、为什么要做动静分离?三大核心优势
-
极致性能:
Nginx 处理静态文件的效率远高于任何应用服务器。它使用异步非阻塞 I/O 模型,单机可轻松应对数万并发连接。 -
减轻后端压力:
将 80% 以上的静态请求拦截在 Nginx 层,后端服务器可以将全部资源用于处理核心业务逻辑,CPU 和内存占用大幅下降。 -
强大的缓存与压缩:
Nginx 可以轻松配置浏览器缓存(expires)、Gzip 压缩、Brotli 压缩等,进一步减少带宽消耗,加速页面加载。 -
高可用性:
即使后端应用暂时宕机,用户依然可以正常访问网站的静态部分(如首页、帮助文档),提升了用户体验。
四、实战:两种主流配置方式
方式一:基于文件后缀名匹配(推荐)
这是最常用、最清晰的方式。通过正则表达式匹配常见的静态文件后缀。
server {
listen 80;
server_name www.example.com;
root /var/www/html; # 网站根目录
# ===== 处理静态资源 =====
location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|txt|woff|woff2)$ {
# 开启高效文件传输模式
sendfile on;
# 设置浏览器缓存过期时间为30天
expires 30d;
# 防止在URL中出现?xxx参数时,缓存失效
add_header Cache-Control "public, immutable";
# 开启Gzip压缩(需在http块中全局开启gzip on;)
gzip_static on;
}
# ===== 处理动态请求 =====
location / {
# 所有未被上面规则匹配的请求,都视为动态请求
proxy_pass http://backend_app; # 转发到后端应用
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
关键指令解释:
~*:表示不区分大小写的正则匹配。expires 30d:设置Cache-Control和Expires响应头,告诉浏览器这些文件30天内无需再次请求。immutable:对于指纹文件(如app.a1b2c3.js),可以加上此标记,即使用户强制刷新也不会重新验证。
方式二:基于目录路径匹配
如果你的项目结构清晰,静态资源都放在特定目录下(如 /static/, /assets/),这种方式更简洁。
server {
listen 80;
server_name www.example.com;
root /var/www/html;
# 静态资源目录
location /static/ {
expires 7d;
# 文件实际存放在 /var/www/html/static/
}
location /assets/ {
expires 30d;
gzip_static on;
}
# 其他所有请求转发给后端
location / {
proxy_pass http://backend_app;
# ... 请求头略
}
}
五、生产环境最佳实践
-
静态资源指纹化:
在构建前端项目时,为文件名添加哈希值(如main.d41d8cd98f.js)。这样,当文件内容变更时,URL 也会变,可以安全地设置超长缓存(如1y),避免用户因缓存看到旧版本。 -
利用
try_files指令:
对于 SPA(单页应用),可以结合try_files实现优雅的路由回退。location / { try_files $uri $uri/ /index.html; }这行配置的意思是:先尝试找
$uri对应的文件,找不到就找$uri/对应的目录,如果还找不到,就返回/index.html。这完美支持了 Vue Router 或 React Router 的 history 模式。 -
安全加固:
禁止访问敏感文件。location ~ /\. { deny all; # 禁止访问 .htaccess, .git 等隐藏文件 }
六、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)