高并发时Nginx缓存CSS后频繁出现404错误怎么办?

诗琪 Dev 阅读 22

最近在优化网站性能时,我尝试在Nginx里给CSS文件设置了长缓存头,但高并发访问时404错误突然增多。已经试过调整proxy_cache_valid和expires参数,但问题依旧…

我的配置大概是这样写的,但不确定哪里出错了:

location ~* .css$ {
    expires 30d;
    add_header Cache-Control "public";
    root /var/www/static; # 这里是否应该用alias?
}

服务器日志显示404请求都在找/static/styles/main.css,但文件明明存在。难道是缓存策略和路径配置冲突了?

我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
Prog.奥哲
这个问题其实挺典型的,很多刚接触 Nginx 缓存配置的同学都容易踩坑。我们一步一步来看,先从你的配置开始分析,再讲解决办法和原理。

---

### 一、你当前的配置问题在哪?

你的配置大概是这样:

location ~* .css$ {
expires 30d;
add_header Cache-Control "public";
root /var/www/static;
}


这个配置有几个**容易忽略但很关键的问题**:

1. **正则匹配写法不严谨**
~* .css$ 会匹配所有以 .css 结尾的请求,但前面没有限制后缀边界,比如 .csssabc.csss 也会被误中。
**建议写成**:~* .css$(注意加了转义点)

2. **路径匹配和 root 的行为不一致**
如果你的 CSS 文件是通过类似 /static/styles/main.css 这样的 URL 访问的,而你在 location 里用了 root /var/www/static;,那最终查找的路径会是:
/var/www/static/static/styles/main.css

因为 root 是把整个 URL 路径拼接到指定目录下。

所以这里应该使用 alias,而不是 root

3. **高并发下 404 的问题**
这个问题其实跟缓存关系不大,而是因为路径配置错误导致有些请求在并发压力下找不到文件,尤其是在缓存未命中或失效时,频繁回源,路径又不对,就会出现大量 404。

---

### 二、正确配置应该怎么做?

#### ✅ 推荐修改后的配置如下:

location ~* ^/.+.css$ {
expires 30d;
add_header Cache-Control "public";
alias /var/www/static/;
}


#### 配置说明:

- ~* ^/.+.css$
更加严谨的正则表达式,确保只匹配合法的 CSS 文件路径。
- alias /var/www/static/;
指定映射路径时,alias 会把匹配的路径部分替换掉,比如请求 /static/styles/main.css 会被映射为 /var/www/static/styles/main.css,这才是你想要的路径。
- expires 30d;
设置浏览器缓存时间,30 天。这个本身没问题。
- add_header Cache-Control "public";
允许中间 CDN、代理缓存这份资源。

---

### 三、关于 rootalias 的区别

这是很多人容易混淆的地方:

- **root** 是拼接路径,比如你访问 /static/styles/main.css,它会去 /var/www/static/static/styles/main.css 找。
- **alias** 是替换路径,同样访问 /static/styles/main.css,它会去 /var/www/static/styles/main.css 找。

所以你之前用了 root,导致每次请求都会多一个 static 目录层,自然就找不到文件了。

---

### 四、建议额外增加的配置项(可选)

为了在高并发下更稳定一些,还可以加上:

open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;


这样可以缓存文件句柄,提升并发访问效率,避免频繁打开/关闭文件句柄。

---

### 五、总结排查思路

1. **先检查路径是否正确**,尤其是 root/alias 的区别;
2. **再看正则是否写得太松散**,避免误匹配;
3. **最后再看缓存配置是否合理**,但不要把问题归咎于缓存策略;
4. **日志要仔细看**,比如你提到的 /static/styles/main.css,一看就知道是路径多了一层。

---

如果你已经改完配置,记得用 nginx -t 检查一下语法,然后 nginx -s reload 重载配置。
如果还有问题,可以贴一下访问日志片段,我们再一起分析。

希望这些能帮你搞定这个问题,加油!
点赞 5
2026-02-03 18:06
晶晶
晶晶 Lv1
你这问题挺典型的,高并发下Nginx缓存出404,大概率是路径配置有问题,或者静态文件的实际位置和Nginx理解的位置对不上。

先说你的配置:rootalias 这俩确实容易搞混。你现在用的是 root,它会把请求路径拼接到后面。如果静态文件的真实路径不对,就会导致Nginx找不着文件,直接返回404。

建议改成 alias,它直接指定目标路径,不会额外拼接:
location ~* .css$ {
alias /var/www/static/; # 注意这里要以斜杠结尾
expires 30d;
add_header Cache-Control "public";
}


另外,高并发时还可能因为文件系统延迟或者磁盘IO跟不上,导致Nginx在某些瞬间找不到文件。可以试试加个 try_files 做兜底处理:
location ~* .css$ {
alias /var/www/static/;
try_files $uri =404; # 如果文件不存在就直接返回404
expires 30d;
add_header Cache-Control "public";
}


最后,检查一下日志里404的请求路径,看看是不是带了多余的前缀(比如 /static),再确认实际文件路径和配置是否一致。如果还是不行,可能得查查后端有没有动静分离没配好,或者API调用里返回的资源路径有问题。

试完这些应该能解决,要是还有问题再细究吧。
点赞 14
2026-01-28 22:14