7.4.8 动态与静态分离实践
动态与静态分离的目标是让静态资源走高效路径(CDN/专用静态服务器),动态请求走应用服务,从而降低后端压力并提升响应速度。实践中通常将静态资源放入独立域名或子域名(如 static.example.com),并通过 Nginx 进行路径路由、缓存与安全控制。
一、原理草图与请求链路
二、场景设计与目录规划
- 静态内容:图片、CSS、JS、字体、下载文件、静态 HTML。
- 动态内容:登录、订单、搜索、API 等需后端计算或鉴权的请求。
- 目录规划示例:
- 应用代码:/opt/app
- 静态资源:/data/static
- 版本化路径:/static/v202401/ 或文件指纹 app.9f3c.js
三、安装与示例部署(含命令解释)
- 安装 Nginx(以 Ubuntu 为例):
sudo apt update
sudo apt install -y nginx
# 解释:更新索引并安装 nginx 软件包
- 准备静态目录与示例文件:
sudo mkdir -p /data/static/v202401
echo "hello static" | sudo tee /data/static/v202401/hello.txt
# 解释:创建静态目录并生成测试文件
- 验证静态文件可访问(配置后测试):
curl -I http://static.example.com/v202401/hello.txt
# 预期:返回 200,包含 Cache-Control/Expires 等缓存头
四、Nginx 动静分离配置示例(完整可用)
文件路径:/etc/nginx/conf.d/site.conf
upstream app_backend {
server 10.0.0.11:8080;
server 10.0.0.12:8080;
keepalive 32;
}
server {
listen 80;
server_name www.example.com;
# 动态请求走后端
location /api/ {
proxy_pass http://app_backend;
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_read_timeout 60s;
add_header Cache-Control "no-store";
}
# 静态资源走本地或静态域名
location /static/ {
root /data;
expires 30d;
add_header Cache-Control "public, max-age=2592000";
access_log off;
try_files $uri =404;
}
}
server {
listen 80;
server_name static.example.com;
location / {
root /data/static;
expires 30d;
add_header Cache-Control "public, max-age=2592000";
add_header Access-Control-Allow-Origin "*";
try_files $uri =404;
}
}
- 加载配置并检查语法:
sudo nginx -t
# 解释:检查配置语法是否正确
sudo systemctl reload nginx
# 解释:平滑重载配置
五、关键命令解释与验证
- 验证静态缓存头:
curl -I http://static.example.com/v202401/hello.txt
# 解释:查看响应头是否包含 Cache-Control/Expires
- 验证动态请求是否走后端:
curl -i http://www.example.com/api/health
# 解释:检查应用健康接口响应,确保 200 且无缓存头
- Nginx 访问日志定位请求路径:
sudo tail -f /var/log/nginx/access.log
# 解释:实时观察静态/动态请求是否分离
六、排错清单(含命令)
- 静态 404:
- 检查静态文件路径与 root:
ls -l /data/static/v202401/hello.txt
# 解释:确认文件存在与权限
- 动态请求返回 502:
- 检查后端端口与健康状态:
curl -I http://10.0.0.11:8080/health
curl -I http://10.0.0.12:8080/health
# 解释:确认后端可达与返回正常
- 缓存未命中:
- 检查响应头:
curl -I http://static.example.com/v202401/hello.txt | egrep -i "cache|expires|etag|last-modified"
# 解释:确认缓存策略是否生效
七、练习(建议完成并提交结果)
1. 在 static.example.com 上新增 app.9f3c.js,设置 30 天缓存并验证响应头。
2. 将 /api/ 的响应头设置为 Cache-Control: no-store,用 curl -I 验证。
3. 使用 try_files 将 /static/ 的 404 请求返回自定义页面 404.html。
4. 模拟后端挂掉,观察 Nginx 返回码(502/504)并记录日志。
八、运维校验清单
- 静态与动态路径是否清晰隔离。
- 静态资源缓存命中率是否达标。
- 动态请求是否正确转发并保留必要请求头。
- 静态域名是否去除 Cookie,CORS 是否生效。