APCu缓存变量无法按预期留存问题求助
APCu缓存条目在TTL有效期内消失的问题排查与解决
环境与症状
环境:Windows Server 2022 Datacenter Azure Edition、IIS、PHP 8.1.23、APCu 5.1.21
配置:APCu共享内存32MB,apc.ttl=3600
症状:设置缓存后首次访问提示不存在并创建,第二次刷新显示缓存存在,第三次刷新(仍在TTL有效期内)缓存条目消失;已配置C:\windows\temp目录的IIS_IUSRS权限,问题未解决
可能的原因
- IIS应用池回收:IIS默认会按时间、内存占用或请求数触发应用池回收,回收后PHP进程重启,APCu作为进程内缓存会被完全清空。
- FastCGI进程回收:PHP的
fastcgi.max_requests设置了进程处理请求的上限,达到阈值后进程重启,缓存随之丢失。 - APCu共享内存不足:32MB的共享内存如果缓存条目较多,APCu会触发自动回收机制,优先删除旧条目(即使未到TTL)。
- Windows临时文件异常:Azure云环境的系统目录读写特性可能影响APCu临时文件的同步,即使配置了权限也可能出现问题。
- PHP与APCu位数不匹配:64位PHP搭配32位APCu扩展(或反之)会导致共享内存管理异常,引发缓存无故消失。
解决办法
- 调整IIS应用池回收策略:
- 打开IIS管理器,找到目标应用池→右键「高级设置」
- 延长「固定时间间隔」(或设为0禁用定时回收),提高内存/请求数回收阈值;若必须回收,开启「重叠回收」减少服务中断,但新进程需重新构建缓存。
- 修改FastCGI配置:
- 编辑
php.ini,将fastcgi.max_requests调至更大值(如10000)或设为0禁用请求数触发的进程回收。 - 确保IIS的FastCGI设置中「实例数」为1(APCu是进程内缓存,多进程会导致每个进程有独立缓存)。
- 编辑
- 增大APCu共享内存:
- 在
php.ini中修改apc.shm_size为64MB或128MB,重启应用池生效。 - 用APCu自带的
apc.php监控脚本查看内存使用率,确认是否因内存不足触发回收。
- 在
- 优化APCu的Windows配置:
- 在
php.ini中设置apc.mktemp_path指向自定义目录(如D:\php_apcu_temp),给该目录分配IIS_IUSRS完全控制权限。 - 设
apc.slam_defense=0避免缓存创建竞争,开启apc.enable_cli=1方便在命令行测试缓存稳定性。
- 在
- 验证位数匹配:
- 执行
php -v查看PHP位数(如x64),确认php_apcu.dll扩展与PHP位数一致,重新安装匹配的APCu扩展。
- 执行
- 用简化脚本排查代码问题:
运行以下脚本多次访问,排除封装类的逻辑错误:<?php $key = 'test_cache'; if (apcu_exists($key)) { echo "缓存存在:" . apcu_fetch($key); } else { apcu_store($key, 'test_value', 3600); echo "缓存不存在,已创建"; } // 输出所有缓存信息 echo "<pre>"; print_r(apcu_cache_info()); echo "</pre>"; ?>
内容的提问来源于stack exchange,提问作者Majickal
相关产品推荐
相关产品推荐

