网站缓存命中率低?先查这几个原因

做站时间一长,多少都会碰到这种怪事:服务器负载不高,带宽也没跑满,可页面就是不太利索。登进控制台一看,缓存命中率低得让人心里发慌。很多人的第一反应是加钱升配,其实这钱花得挺冤。命中率低,十有八九不是机器不行,而是请求压根没落到缓存上。今天我就按自己踩坑的顺序,把从命令行验证到四类原因排查的路子捋一遍,最后再教你用日志核实效果,别再对着那条曲线干瞪眼。

缓存命中率

缓存命中率到底是个啥,先给个判断标准

很多人只知道网站缓存能提速,却不清楚网站缓存还有命中率这个说法。说白了,命中率就是命中缓存的请求数除以总请求数,意思是这一批请求里有多少不用回源站、直接从边缘节点就把东西取走了。这个数没有统一标准,静态资源和动态页面必须分开看:图片、样式表、脚本这类文件,做得好绝大部分请求都该命中;接口、搜索页、结算页本来就不该缓存,占比一高自然把整体数字往下拽。所以看数字之前先分清对象,别拿一个笼统的百分比吓自己。各家控制台的统计口径不完全一样,具体以服务商页面说明为准。

第一步:用 curl -I 看 X-Cache 和 Age

排查别急着翻配置文件,先动手拿证据。挑一个具体的静态文件地址,比如 https://www.example.com/static/app.js ,在命令行里连着敲几次 curl -I 紧跟这个地址,重点看两处:一是 X-Cache 这类头部到底是 HIT 还是 MISS,各家叫法不一样,有的写 X-Cache-Status,有的写 CF-Cache-Status;二是 Age 头,命中时这个数字会随时间往上走,一直停在 0 或者根本没这个头,基本就是没命中。提醒一句,HEAD 请求有些节点不缓存,要是每次都 MISS,换成 curl -s -o /dev/null -D – 加地址再打一遍。

第二步:进控制台看曲线,别只盯着一个数字

命令行只能证明某一条 URL 的状态,想看全局还得回控制台。进去之后至少看三个东西:缓存命中率曲线、回源请求数、回源流量。真正的关键是回源请求数,它要是跟着总请求一起往上涨,说明大量请求都在往源站跑,命中率低就算实锤了。接着按域名、按路径、按时间段拆开看,再翻一翻回源次数最多的 URL 排行,排在前面的那几条往往就是元凶,比你自己瞎猜快得多。曲线要是突然掉一个坑,多半是那个时间点改过配置、上过新规则,或者源站出了状况,对着时间点回溯就行。

原因一:URL 带着随机参数或者统计参数到处跑

这是最常见的一条。缓存是拿完整 URL 当钥匙的,参数不一样就算两个不同的对象。分享出去的链接挂着 utm_source、utm_medium,站内统计脚本又给请求拼上 spm、from、_t 这类参数,有些主题还爱给静态文件加个随机数版本号,结果同一个页面被拆成几十把钥匙,每把都得回源一趟,缓存等于白建。排查也不难,去回源 URL 排行里看那些带问号的地址,或者在访问日志里筛一把带参数的请求,看看是不是重复得离谱。要是同一份内容天天被当成新对象处理,那命中率再怎么调也上不去。

proxy_cache_key 把统计参数从缓存键里剔出去

治这个病的核心是重建缓存键,让带统计参数的请求和干净请求共用同一份缓存。在 Nginx 里用 set 定义一个 $cache_key,默认取 $scheme$host$request_uri;再加一条判断,请求里命中 utm_ 这类统计参数时,就把 $cache_key 换成不带参数的 $scheme$host$uri;最后用 proxy_cache_key $cache_key; 让它生效。静态资源更省事,参数不影响文件内容,键直接写 $scheme$host$uri 就行。这个坑我踩过:条件一放宽,分页和搜索参数也被一起丢掉,不同页面共用一份缓存,用户就看到串页内容,所以只在参数不影响输出时才这么干。

原因二:源站给页面回了 private 或者 no-cache

第二类原因出在源站而非边缘节点。有些主题和插件图省事,给所有响应都塞上 Cache-Control: private、no-cache,再带个 Set-Cookie,节点一看就不敢缓存,请求只能次次回源。这种情形在 WordPress 上尤其常见,登录态判断和会话 cookie 都可能触发。查法仍是看响应头:curl -I 打一下页面,盯住 Cache-Control 和 Set-Cookie 两行。治法是分人群:匿名访客给 public 配合理的 max-age,登录用户直接绕开;静态资源按文件名加哈希,配一年期强缓存。用 proxy_ignore_headers 强忽略这些头,务必想清后果,登录态页面被缓存出去就是串号事故。

原因三:回源 Host 和站点对不上,缓存各存各的

这个坑很隐蔽:回源请求一直不少,可源站日志里的 Host 却不是你的站点名。回源时带的 Host 决定 Nginx 匹配哪个 server 块,对不上就可能落到默认站点,拿到 404 或别人的首页,缓存就建不起来。排查分两步:先翻源站日志,看回源请求的 Host 到底是谁;再在源站机器上试一次,curl -I -H “Host: www.example.com” http://服务器IP/ ,看返回对不对。修的时候两头对齐,源站把 server_name 写全,或加个 default_server 兜底,控制台那边把回源 Host 设成加速域名。顺带说下,回源协议写成 https 但源站只听 80,一路全是跳转,命中率也被拖下去。

原因四:后台接口和动态页被规则排除,这属于正常

第四类原因得冷静看待:后台地址、登录页、下单结算、接口请求、带登录 cookie 的访问,本来就该排除在缓存之外。这些请求占比一高,整体命中率一定难看,但它不是故障,是设计如此。判断标准很简单,把回源请求按路径分组统计一下,如果大头集中在 /wp-admin/、/wp-login.php、/api/ 这类路径上,那就别折腾缓存规则了,方向本身就错了。真想把这部分也优化掉,思路是分开治:静态资源单独放一个目录或者子域名,给足长缓存;动态页面别硬缓存整页,改用对象缓存顶住数据库压力,或者只给匿名访客做页面缓存,登录用户直接绕过。

改完怎么验证:日志里统计命中率

配置改完别凭感觉,得用数据核账。Nginx 自带一个 $upstream_cache_status 变量,它会告诉你每个请求是 HIT、MISS、BYPASS、EXPIRED 还是 STALE。先给响应加个头,方便命令行实时看:add_header X-Cache-Status $upstream_cache_status; 再把它写进日志格式里,攒一段时间后统计:awk ‘{print $3}’ /var/log/nginx/cache.log | sort | uniq -c | sort -rn 出来的结果里 HIT 占多少一目了然。统计前记得清一次缓存、切一次日志让时间段对齐;也别拿几十条请求下结论,至少跑够一个访问高峰。

最后说几句掏心窝的。命中率这东西出问题,九成不是钱不够,而是缓存键没设计好、响应头没给对、规则没配平。排查顺序也别乱:先用 curl -I 看单条 URL 的头部,再进控制台看整体曲线和回源排行,然后按参数、响应头、回源 Host、动态路径这四条线逐个排除,最后用 $upstream_cache_status 的日志把效果验回来。记住一条铁律,改任何规则之前先备份配置、想清楚影响范围,上线后盯一两天数字再决定保留还是回滚。愿你下次打开控制台,看到的是那条稳稳往上走的曲线,而不是满屏的 MISS。

【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!

(0)
爱家的头像爱家
网站缓存写入失败?先查权限和磁盘
上一篇 2026-09-10 19:23
东莞网站建设seo_网站推广(SEO设置)
下一篇 2024-07-05 22:31

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

广告合作

QQ:14239236

在线咨询: QQ交谈

邮件:asy@cxas.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信