先看静态资源占比和缓存命中率能否覆盖拆分成本,再用nginx location规则把静态请求拦在应用服务器前面,配合redis info与nginx日志持续监控命中率,才能避免拆完资源没省到、问题反而更多。
很多站点把图片、CSS、JS 和动态接口混在同一套应用服务里,应用服务器一边查数据库拼业务逻辑,一边吐静态文件,连接数被占满,带宽被消耗,CPU 还要处理大量磁盘 IO,动静分离就是把这件事拆开:静态文件走 nginx 直接返回或对象存储,动态请求继续交给后端,但拆之前得先评估,不是所有站点都适合。
动静分离方案怎么做评估?先算三笔账
静态资源占比决定拆分价值
打开浏览器开发者工具的 Network 面板,按类型筛选 js、css、img、font,看这些静态请求在总请求里占多大比例,再翻一下 nginx 的 access log,统计 URI 后缀分布,如果静态请求占了七成以上,动态接口只有两三成,拆分价值就很高,反过来,如果站点以实时数据、个性化内容为主,静态文件很少,拆了也省不了多少资源。
- 用
awk统计日志中静态后缀出现次数:
awk '{print $7}' /var/log/nginx/access.log | grep -oE '.(jpg|png|css|js|woff2)' | sort | uniq -c | sort -rn - 静态请求占比越高,动静分离优先级越高。
- 资源类型要区分:商品图、用户头像这类文件通常较大,拆分收益明显;小图标、短 CSS 文件收益相对有限。
服务器负载与带宽成本对比
拆分前,应用服务器要同时处理动态逻辑和静态文件传输,连接数和内存占用都偏高,拆分后,nginx 直接返回静态文件,应用服务器的连接数下降,后端数据库压力也会减轻,但静态文件从应用服务器目录挪到独立目录或对象存储,会带来新的带宽出口。
| 指标 | 拆分前 | 拆分后 |
|---|---|---|
| 应用服务器连接数 | 高 | 低 |
| 静态文件响应速度 | 依赖应用性能 | nginx 直接返回,更快 |
| 运维复杂度 | 低 | 中 |
| 带宽成本出口 | 应用服务器 | nginx/对象存储/CDN |
| 适用场景 | 静态资源少、动态为主 | 静态资源多、缓存友好 |
如果站点已经接入了 CDN,静态请求大部分被边缘节点扛住,源站动静分离的收益会打折扣,这时优先优化 CDN 缓存策略,比急着拆源站更划算。
缓存命中率是评估的先行指标
行业共识认为,静态资源命中率若能稳定在九成以上,动静分离方案才算真正跑通,拆分之前,先观察现有 CDN 或浏览器缓存命中率,如果命中率很低,说明缓存策略本身有问题,比如响应头没有 Cache-Control、文件命名带版本号时更新不同步,直接上动静分离只会把问题搬到新架构里。
nginx动静分离配置教程:从location到缓存命中率监控
基础location规则与expires设置
nginx 的 location 正则匹配常见静态后缀,配合 expires 让浏览器长时间缓存,典型配置如下:
server {
listen 80;
server_name example.com;
# 静态资源由nginx直接读取本地目录
location ~ .(jpg|jpeg|png|gif|webp|css|js|woff2|svg)$ {
root /data/static;
expires 30d;
add_header Cache-Control "public, max-age=2592000";
access_log off;
}
# 动态请求转发给应用服务器
location /api/ {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
access_log off 能减少静态请求的日志写入量,降低磁盘 IO,静态文件目录建议单独挂载,不要和应用代码混在一个根目录下,避免误删或权限混乱。
缓存命中率监控命令:nginx日志统计
nginx 配了 proxy_cache,可以在日志格式里带上 $upstream_cache_status 变量,记录每次请求是 HIT 还是 MISS。
log_format cache '$remote_addr - $request - $status - $upstream_cache_status'; access_log /var/log/nginx/cache.log cache;
然后用 awk 统计命中状态:
awk '{print $NF}' /var/log/nginx/cache.log | sort | uniq -c
输出里如果 MISS 数量偏高,说明缓存键不稳定或缓存空间不足,把 HIT 总数除以 HIT+MISS 总数,就是当前 nginx 缓存命中率,建议把这个值接入 Prometheus 或 Zabbix,设置持续走低告警。
redis缓存命中率监控命令
动态数据如果用的是 redis 缓存,直接执行:
redis-cli info stats | grep -E 'keyspace_hits|keyspace_misses'
计算方式就是 keyspace_hits / (keyspace_hits + keyspace_misses),这个值要配合业务场景看:用户会话类数据命中率天然较低,配置类、热点商品类数据命中率应该保持在较高水平,把两个指标做成监控面板,每次发布后对比变化趋势,能快速发现缓存键改造是否引入问题。
redis缓存命中率低怎么解决?从五个环节排查
缓存命中率一旦持续走低,不要先怀疑 redis 本身,多数情况下问题出在缓存键设计、过期时间或淘汰策略上,按下面顺序排查,基本能覆盖大部分场景。
缓存键设计是否合理
缓存键如果包含随机参数、时间戳、用户 ID,同一个数据会生成大量不同键,命中率自然低,统一键命名规范,例如用 user:profile:{uid} 而不是 user_profile_uid_{uid}_v1,排查命令:
redis-cli --scan --pattern 'prefix' | head -20
抽样看键的分布,如果同一类数据出现大量后缀变体,就是键设计有问题,去掉不必要的 query 参数,只保留核心业务标识。
缓存过期时间是否过短
过期时间设太短,数据还没被再次访问就失效,查看某个 key 的剩余时间:
redis-cli TTL key
返回 -1 表示不过期,返回 -2 表示 key 不存在,热点配置数据可以设长一些,用户会话短一些,不同业务设置不同 TTL,不要一刀切。
缓存淘汰策略是否合理
查看当前淘汰策略:
redis-cli config get maxmemory-policy
如果返回 allkeys-lru,redis 会在内存满时淘汰最近最少使用的 key,业务如果存在明显热点 key,可以改用 volatile-lru,只淘汰设置了过期时间的 key,调整前先评估内存使用情况,避免误淘汰核心数据。
缓存预热是否缺失
新版本上线或 redis 重启后,缓存是空的,大量请求直接打到数据库,命中率瞬间掉底,可以在低峰期用脚本预热热点 key,比如把数据库里的热门商品、配置项批量写入 redis,预热脚本要放在发布流程里,不要每次手动执行。
缓存穿透与缓存击穿
穿透是请求不存在的 key,每次都查数据库,用布隆过滤器或空值缓存拦截,击穿是热点 key 过期瞬间大量并发,用互斥锁或逻辑过期解决,两者都会拉低命中率,但处理方法不同,先通过日志确认是哪种情况。
动静分离和cdn区别是什么?别把两者划等号
动静分离是源站内部把静态请求和动态请求分流,通常由 nginx 或网关完成,CDN 是地理分布式缓存节点,把静态资源缓存到离用户近的边缘节点,两者可以叠加:先做 nginx 动静分离,再把静态域名接入 CDN,进一步加速。
| 维度 | 动静分离 | CDN |
|---|---|---|
| 作用范围 | 单台或集群内部 | 全球/区域边缘节点 |
| 主要解决 | 应用服务器资源占用 | 用户访问延迟和跨地域带宽 |
| 配置位置 | nginx/server块 | DNS解析/CNAME接入 |
不少运维把动静分离和 CDN 当成二选一,其实场景不同,源站压力大、静态文件多,先做动静分离;用户分布广、跨地域访问慢,再上 CDN,两者叠加后,静态资源请求从边缘节点直接返回,源站只处理少量回源请求。
动静分离方案评估不是看别人做了就跟风,而是先算静态资源占比、缓存命中率、服务器负载三笔账,配置落地后,nginx 日志与 redis info 两条监控线要持续跑,缓存命中率一旦持续走低,先查缓存键、过期时间、淘汰策略,再查穿透和击穿,把评估和监控闭环起来,动静分离才不会变成一次性的配置改动。
缓存命中率监控相关问答
动静分离方案怎么做才能避免缓存穿透?
缓存穿透要在入口层做参数校验,过滤明显非法的 key;缓存层对空结果设置短过期,或使用布隆过滤器拦截不存在的数据,这样可以避免大量不存在的 key 打到数据库,从源头减少穿透对命中率的冲击。
redis缓存命中率低怎么解决?
先执行 redis-cli info stats 查看 keyspace_hits 和 keyspace_misses,计算命中率,然后按顺序排查:缓存键是否包含随机参数、TTL 是否太短、maxmemory-policy 是否与业务匹配、重启后是否缺少预热、热点 key 是否击穿,每项都可以用对应命令验证,逐项排除后命中率会明显回升。
动静分离和cdn区别在哪里?
动静分离是源站内部把静态请求和动态请求分流,减少应用服务器压力;CDN 是把静态资源缓存到边缘节点,减少用户访问延迟,两者配置位置和优化目标不同,通常先做动静分离,再把静态域名接入 CDN,叠加使用效果最好。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/646037.html





