连载中 6/15

动静分离:把静态资源从应用手里抢出来

2026-09-25 · 11 阅读 · 0 评论 · 0 赞

为什么要分离

一个大促页面引用了 40 张图、8 个 CSS、12 个 JS——这些请求如果全打到 Tomcat,每个都占一个线程去做"读文件吐文件"的活,业务线程池被静态请求挤满,接口 RT 跟着遭殃。而 Nginx 处理静态文件走 sendfile:文件从磁盘直接进内核缓冲区再到网卡,不进用户态、不占应用线程,单机轻松几万 QPS。动静分离的本质:让贵的算力只干业务,便宜的活交给专业的。

root 与 alias 的大坑

location /static/ {
    root /data/www;        # 拼接规则:/data/www + /static/logo.png
}                          # 最终读 /data/www/static/logo.png

location /static/ {
    alias /data/www/;      # 替换规则:/static/ 整段换成 /data/www/
}                          # 最终读 /data/www/logo.png
#
# 记法:root 是"加上",alias 是"换成"
# 经典翻车:想用 alias 却写了 root(或反之),404 找半小时
# alias 末尾斜杠要对齐:/data/www/ 配 location /static/ ——注意两边都带

静态资源的缓存策略

静态资源要跟浏览器配合:带指纹的文件名 + 长强缓存。构建工具输出的 app.a3f9c2.js 内容一变文件名就变,可以放心给一年缓存(expires 365d);而 index.html 是引用入口,必须不缓存或短缓存,否则用户拿到旧 HTML 引不到新资源。这套"入口不缓存、指纹长缓存"的组合拳,是前端发布不乱套的基石——呼应缓存系列里"给谁缓存、缓存多久"的思路。

目录安全

location /static/ {
    alias /data/www/;
    autoindex off;                    # 默认就是 off,别手贱打开
    # autoindex on 会列目录:/static/ 直接展示全部文件——信息泄露
}
# 敏感文件一律封死
location ~* .(env|git|bak|sql|log)$ {
    return 404;
}
# .env、.git/config、备份包被扫到就是数据泄露事故,全封掉最稳

一份完整的动静分离 server

server {
    listen 80;
    server_name shop.example.com;

    location ^~ /static/ {            # ^~ 截断正则,静态优先(呼应 location 篇)
        alias /data/www/static/;
        expires 365d;
        add_header Cache-Control "public, immutable";
    }
    location /uploads/ {              # 用户上传:可读,但禁执行、限缓存
        alias /data/uploads/;
        expires 7d;
    }
    location / {                      # 其余全走应用
        proxy_pass http://app_server;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

这个骨架能直接抄走改改上线。静态资源还有一半收益没拿到——压缩和缓存头,下一篇把它补齐。

☕
503

10 年全栈工程师 · 503咖啡馆主理人

#动静分离#root与alias#sendfile#静态资源缓存#目录安全

评论 (0)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10101 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9873 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9294 阅读 · 21 评论 · 287 赞