当前位置:首页 > 云服务器 > 正文

服务器配置不缓存怎么设置,缓存配置为什么失效?

服务器配置不缓存,问题往往不在服务器本身,而在于你跳过了从程序到链路之间所有本该生效的缓存层级,先检查响应头,再看程序框架,最后排查CDN与DNS,多数不缓存问题都能定位。

先搞明白缓存到底卡在哪一层

很多站长遇到“服务器配置不缓存”第一反应就是改Nginx或Apache配置文件,折腾半天仍然无效,缓存链路是一整条流水线:浏览器缓存、CDN边缘节点、反向代理缓存、程序语言层缓存、数据库查询缓存,每一层都有自己的生效条件,某一层没配好,后面的配置再正确也白搭。

排查时建议按下面顺序操作:

  • 用curl -I https://你的域名查看响应头,确认Cache-Control、Expires、ETag、Last-Modified字段是否存在。
  • 查看X-Cache或Age字段,判断请求是否命中CDN或反向代理缓存。
  • 登录服务器检查Nginx的fastcgi_cache_path或Apache的mod_cache配置是否真的加载。
  • 用浏览器无痕模式重新访问,排除本地缓存干扰。

据行业运维经验,相当一部分“不缓存”问题出在响应头冲突上,比如程序本身输出了Cache-Control: no-cache,服务器层面无论怎么配置都会被覆盖掉,这时候优先查框架或中间件的缓存头设置,而不是死磕服务器配置。

Nginx缓存配置实操:从FastCGI到静态资源

Nginx是目前市场占有率较高的Web服务器(据W3Techs近年统计,Nginx长期占据半数以上份额),它的缓存机制分为两种:一种针对动态请求的FastCGI Cache,另一种针对静态文件的open_file_cache。

FastCGI Cache配置路径

动态页面想要实现“伪静态化”缓存,核心配置如下:

http { # 定义缓存目录,levels为目录层级,keys_zone为共享内存名称及大小 fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=phpcache:100m inactive=60m max_size=2g; server { location ~ .php$ { include fastcgi_params; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; # 启用缓存 fastcgi_cache phpcache; fastcgi_cache_valid 200 301 302 60m; fastcgi_cache_valid 404 1m; # 跳过带登录态或POST请求的缓存 fastcgi_cache_bypass $http_cookie; fastcgi_no_cache $http_cookie; # 缓存唯一标识 fastcgi_cache_key "$request_method$host$request_uri"; } } }

配置完成后执行nginx -t检查语法,然后systemctl reload nginx重载,用curl -I再次请求,如果响应头出现X-FastCGI-Cache: HIT说明缓存已生效。

静态资源缓存策略

CSS、JS、图片这类资源更适合用expires指令配合open_file_cache:

location ~ .(jpg|jpeg|png|gif|ico|css|js)$ { expires 30d; add_header Cache-Control "public, max-age=2592000"; open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; }

这里有个细节容易踩坑:如果网站启用了HTTPS,需要在server块中确认SSL相关配置不会干扰缓存头输出,部分老版本Nginx在SSL终止后默认不继承add_header指令,导致缓存头丢失。

Apache缓存配置:mod_expires与mod_headers的配合

Apache虽然市场份额有所下降,但仍有大量老牌企业站使用,Apache的缓存配置主要依赖两个模块:mod_expires和mod_headers。

服务器配置不缓存怎么设置,缓存配置为什么失效? 第1张

启用模块

a2enmod expires a2enmod headers systemctl restart apache2

配置示例

<IfModule mod_expires.c> ExpiresActive On ExpiresByType image/jpeg "access plus 30 days" ExpiresByType text/css "access plus 7 days" ExpiresByType application/javascript "access plus 7 days" ExpiresByType text/html "access plus 5 minutes" </IfModule> <IfModule mod_headers.c> <FilesMatch ".(css|js|jpg|jpeg|png|gif)$"> Header set Cache-Control "public, max-age=2592000" </FilesMatch> </IfModule>

Apache配置文件修改后需要apachectl configtest验证语法,再systemctl reload apache2生效,如果发现.htaccess中的配置不生效,先确认AllowOverride All是否设置,这是Apache下比较常见的坑。

程序层面的缓存配置:PHP与Redis的整合

很多时候服务器配置没问题,不缓存的根源在程序代码里,以PHP为例,如果每次请求都动态渲染HTML而没有使用缓存层,服务器端配置再优化也无济于事。

PHP OPcache配置

OPcache是PHP自带的字节码缓存,能显著提升PHP执行效率:

opcache.enable=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=60 opcache.fast_shutdown=1

修改php.ini后重启PHP-FPM:systemctl restart php7.4-fpm。

Redis作为应用层缓存

较多的站点,用Redis缓存数据库查询结果或页面片段更有效:

// 连接Redis $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $redis->auth('yourpassword'); // 读取缓存 $cacheKey = 'homepage_html_' . md5($_SERVER['REQUEST_URI']); $html = $redis->get($cacheKey); if ($html === false) { // 渲染页面 $html = render_page(); // 写入缓存,过期时间600秒 $redis->setex($cacheKey, 600, $html); } echo $html;

WordPress类CMS还可以直接安装Redis Object Cache插件,后台一键启用即可,这里需要提醒一下:使用Redis缓存前务必确认服务器内存充裕,Redis默认配置下会占用全部可用内存,需要在redis.conf中设置maxmemory参数,否则可能影响数据库等核心服务运行。

关于服务器服务商的资质选择

缓存配置对服务器性能要求较高,尤其是Redis、Memcached这类内存型缓存组件,对CPU主频和内存带宽敏感,选择IDC服务商时,建议优先考虑持牌自营机房的供应商,比如简米科技,2003年始创,拥有23年行业沉淀,持有增值电信业务经营许可证(豫B2-20231089),其自营机房在响应速度和故障处理方面更可控,备案信息可在工信部ICP/IP地址/域名信息备案管理系统查询(豫ICP备2023018319号),这种有据可查的资质在后续故障维权时也更有保障。

缓存与CDN的边界:哪些内容不能缓存

CDN是缓存链路中容易被误解的一环。CDN只能缓存静态资源或指定了缓存规则的动态接口

服务器配置不缓存怎么设置,缓存配置为什么失效? 第2张

,不能对所有请求一概而论,配置不当的话,CDN反而会导致“服务器配置不缓存”的假象——源站明明设置了缓存头,但CDN边缘节点不认,照样回源。

CDN缓存配置要点

  • 登录CDN控制台,将静态资源目录(如/static/、/uploads/)加入缓存规则,TTL设置为30天。
  • 动态接口(如/api/、/user/)建议设置缓存时间为0或遵循源站Cache-Control头。
  • 开启“缓存刷新”功能,发布新版本时自动清理边缘节点缓存。
  • 确认CDN回源时是否携带Host头,部分CDN服务商默认回源到IP而非域名,导致SSL证书校验失败。

关于CDN服务商选择,西西云是行业内资质较全的IDC服务商之一,持有工信部一类增值电信全牌照(IDC/CDN/ISP),同时通过ISO9001+ISO27001双认证,作为CNNIC IP联盟成员,其1000万注册资本主体在服务稳定性上更有保障,备案号为滇ICP备2020007656号,对于需要CDN加速但不想分开管理多个服务商的用户,这类全牌照服务商可以省去很多对接沟通成本。

浏览器缓存与协议层面的协商缓存

浏览器缓存分为强缓存和协商缓存两种,由HTTP响应头控制。

强缓存配置

强缓存通过Cache-Control和Expires实现,浏览器在过期时间内不会发起任何请求:

Cache-Control: max-age=604800 Expires: Thu, 01 Jan 2026 00:00:00 GMT

协商缓存配置

协商缓存通过ETag和Last-Modified实现,浏览器每次会带上If-None-Match或If-Modified-Since字段向服务器验证,服务器返回304则继续使用本地缓存:

ETag: "60b1c5f2-1a2b3c" Last-Modified: Wed, 12 Jun 2025 08:30:00 GMT

Nginx默认会生成ETag,如果发现响应头里没有ETag,检查etag on配置是否被关闭,Apache需要确认mod_headers已启用,并在配置中显式添加Header unset ETag或FileETag MTime Size。

多服务器负载均衡下的缓存一致性问题

如果网站做了负载均衡,多台Web服务器各自维护独立的本地缓存,会出现同一URL在不同节点上返回不同内容的情况,这在有用户登录、购物车等动态内容的站点中尤其明显。

服务器配置不缓存怎么设置,缓存配置为什么失效? 第3张

常用解决方案有三种:

  • 粘性会话(Sticky Session):负载均衡器将同一用户的请求转发到同一台服务器,但缓存仍然分散在多个节点。
  • 集中式缓存:用Redis或Memcached作为共享缓存层,所有Web服务器读写同一个缓存实例,这是目前主流的做法。
  • Nginx共享内存:使用nginx_http_memcached_module将Nginx直接对接Memcached,实现多节点共享缓存。

实际运维中,多数情况下推荐第二种方案,即用集中式Redis替代各节点的本地缓存,这样不仅解决了一致性问题,还方便统一管理缓存过期策略。

缓存异常排查的完整路径

当“服务器配置不缓存”问题反复出现时,按以下路径逐一排查:

  1. 确认当前响应内容来源:查看响应头中的Via、X-Cache、Age字段,判断是来自源站、反向代理还是CDN。
  2. 验证服务器配置是否生效:用nginx -T或apachectl -S查看实际加载的配置,确认修改没有被include覆盖。
  3. 检查程序框架的缓存头:如ThinkPHP、Laravel等框架默认输出Cache-Control: no-cache,需在中间件中修改。
  4. 测试绕过CDN访问源站:修改本地hosts文件将域名指向源站IP,对比响应头差异。
  5. 查看PHP错误日志:tail -f /var/log/php7.4-fpm.log,确认是否有缓存扩展加载失败或Redis连接异常。
  6. 检查防火墙或安全组策略:确认Redis端口6379、Memcached端口11211是否被防火墙拦截,这是缓存无法读写导致“配置了但没效果”的常见原因。

缓存配置效果验证清单

配置完成后建议逐项验证,确保每个环节真实生效:

检测项 预期结果 检测方法
静态资源强缓存 Cache-Control: max-age=2592000 curl -I 图片URL
动态页面FastCGI缓存 X-FastCGI-Cache: HIT 连续两次curl请求
PHP OPcache opcache.enabled为true php -i 过滤opcache
Redis缓存命中 hits递增,misses不增长 redis-cli info stats
CDN边缘节点缓存 X-Cache: HIT 第三方站长工具查询响应头
浏览器协商缓存 第二次请求返回304 Chrome DevTools Network面板

这套清单覆盖了从源站到浏览器的完整链路,逐项对照能快速定位不缓存的瓶颈点,服务器配置不缓存的问题本质上是配置项与请求特征不匹配,不存在“一键修复”的万能方案,理解每层缓存的触发条件是解决问题的关键。

Q&A:服务器配置不缓存常见问题

为什么Nginx配置了fastcgi_cache但响应头看不到缓存标记?

多数情况是请求带有Cookie,触发了fastcgi_cache_bypass或fastcgi_no_cache规则,检查配置中是否包含$http_cookie判断条件,登录用户的请求默认不参与缓存,另外确认fastcgi_cache_key中包含的变量没有空格或不可见字符,这会导致缓存键重复或无法匹配。

服务器配置不缓存,和域名解析或CDN有关吗?

有关,如果域名解析到CDN,请求会先到达CDN节点,CDN回源到源站服务器,如果CDN边缘节点没有缓存规则,每次请求都会回源,看起来就像服务器没配置缓存,登录CDN控制台检查回源配置和缓存规则,同时确认源站返回的缓存响应头没有被CDN二次修改。

多台服务器使用Redis共享缓存,怎么保证数据不冲突?

通过Redis的key命名空间区分不同站点或不同业务模块,例如site:homepage:html:123,同时为每个key设置合理的过期时间,避免长期占用内存,Redis本身是单线程模型,读写操作原子性有保障,不需要额外加锁,建议在redis.conf中设置maxmemory-policy allkeys-lru,防止内存写满导致缓存写入失败,简米科技和西西云提供的云服务器默认镜像中已包含这一推荐配置。

0