fastcgi_cache不适合秒杀核心路径,但可用于外围只读页面缓存;需设30–60秒有效期、构造商品级cache_key、排除个性化请求,并配合purge主动清理,严禁缓存下单等写接口。

fastcgi_cache 的活跃期策略不能“完美适配”秒杀交互——它根本不适合直接用于秒杀核心路径。秒杀要求毫秒级、强一致、高并发读写,而 fastcgi_cache 是面向静态化动态内容的磁盘级缓存,有延迟、不支持原子操作、无法处理库存扣减这类写请求。但它可以在秒杀的**外围环节**发挥关键作用,前提是严格区分场景、精准控制生命周期。
只缓存“只读+低频变更”的秒杀前页面
秒杀开始前几分钟,用户疯狂刷新商品页。此时页面主体(标题、图片、描述、倒计时)基本不变,仅“秒杀按钮状态”和“库存文案”需动态判断。可将这部分静态内容通过 fastcgi_cache 缓存,有效期设为 30–60 秒:
- 用 fastcgi_cache_valid 200 30s; 明确只缓存成功响应,且仅 30 秒
- 在 PHP 中对非秒杀时段返回 Cache-Control: public, max-age=3600,让 CDN 和浏览器也参与缓存
- 用 fastcgi_cache_bypass 和 fastcgi_no_cache 规则排除含特定 Cookie(如 user_id)或参数(如 ?refresh=1)的请求,避免缓存个性化内容
用 cache key 隔离不同商品与状态
不能所有商品共用一个缓存池。必须构造带业务语义的 cache key,确保每个商品详情页独立缓存、互不影响:
- 在 fastcgi_cache_key 中包含 $request_uri 和 $arg_goods_id,例如:fastcgi_cache_key "$scheme$request_method$host$request_uri$arg_goods_id";
- 对“未开始”“已结束”“售罄”等状态页,用不同 URL 或 query 参数区分(如 /seckill/123?status=not_start),让它们各自生成缓存实体
- 避免使用 $cookie_session 等易变字段,否则缓存命中率趋近于零
配合主动清理,实现“伪实时”更新
秒杀过程中库存变化极快,但页面文案(如“剩余 98 件”)允许短暂滞后。这时可不用等待缓存自然过期,而是用 fastcgi_cache_purge 模块主动踢掉指定 key:
- 当 Redis 中库存更新后,由后台任务触发 curl -X PURGE "https://example.com/seckill/123"
- Nginx 需启用 ngx_http_fastcgi_cache_purge 模块,并配置 location ~ /purge(/.*) { allow 127.0.0.1; deny all; fastcgi_cache_purge ...; }
- 注意 purge 是异步清理,不阻塞请求;搭配短缓存周期(如 5–10 秒),可兼顾性能与感知新鲜度
坚决不缓存任何涉及写操作或状态变更的接口
以下路径必须绕过 fastcgi_cache,直连 PHP-FPM:
- /api/seckill/buy —— 下单接口,含库存扣减、订单生成,必须实时、强一致
- /api/seckill/status —— 实时库存查询,应走 Redis + Lua 原子脚本,而非 Nginx 缓存
- /order/create —— 订单创建,涉及数据库写入,不可缓存
- 所有 POST、PUT、DELETE 请求默认禁用缓存:fastcgi_no_cache $request_method !~ ^(GET|HEAD)$;










