要让ThinkPHP6真正扛住1万并发请求,必须替换PHP-FPM为Swoole或Workerman,启用官方扩展think-swoole/think-worker实现生命周期隔离,禁用file缓存,配置Redis连接池、分片、hash tag及分级缓存策略,并前置日志监控与降级机制。

要让 ThinkPHP6 真正扛住 1 万并发请求,单靠框架默认缓存或文件缓存完全不可行。核心不是“加缓存”,而是构建分层、隔离、可伸缩的缓存体系,并配合底层运行模型升级——否则缓存本身会成为瓶颈。
必须换掉 PHP-FPM,启用 Swoole 或 Workerman
ThinkPHP6 原生是同步阻塞模型,每请求占一个 PHP 进程,1 万并发意味着至少 1 万 PHP-FPM 子进程,内存和上下文切换直接打爆。Swoole 协程能用少量进程处理数万连接,Workerman 的事件循环也大幅降低资源消耗。
- 使用官方扩展
think-swoole或think-worker,它们已封装生命周期管理,避免全局变量污染和连接泄漏 - 禁用框架内置 file 缓存(如
runtime/cache/),它在常驻内存模式下会越积越多,且无自动清理机制 - 反向代理(如 Nginx)需显式配置
proxy_http_version 1.1和Connection "keep-alive",否则协程长连接会被断开
Redis 必须做连接池 + 分片 + hash tag
单 Redis 实例在 1 万并发下极易成为热点,连接数、QPS、内存带宽都会触及上限。不能只配 host 和 port,要真正适配集群与高负载场景。
- 使用
predis/predis替代原生 phpredis 扩展,才能支持 Redis Cluster;TP6 默认驱动不识别nodes数组,硬填会降级为单点 - 所有缓存 key 强制加 hash tag,例如
{user:1001}:profile,确保同一用户数据路由到同一 slot,避免跨节点查询 - 在
database.php中为 Redis 配置连接池参数:'pool_size' => 200、'pool_get_timeout' => 3,防止协程争抢连接超时
缓存策略按访问特征分级落地
不是所有数据都适合放 Redis,也不是所有接口都值得缓存。重点保护数据库的“热路径”,同时避免缓存雪崩、穿透、击穿。
立即学习“PHP免费学习笔记(深入)”;
- 热点数据预加载:用定时任务提前把首页推荐、商品类目等高频数据写入 Redis,过期时间设为随机值(如 3600±300 秒),防集中失效
-
读多写少数据用 Cache::remember():比如用户资料,自动判断命中并回填,搭配
Cache::tag('user')实现批量刷新 -
防穿透加布隆过滤器或空值缓存:对非法 ID 查询返回
null并缓存 5 分钟,避免恶意请求直击 DB - 慎用全量缓存页面:TP6 页面缓存依赖模板编译,常驻进程下易出错;改用 Nginx FastCGI 缓存更稳,但需配合 Cache-Control 和 ETag 控制粒度
日志、监控与降级必须前置设计
1 万并发下,缓存系统一旦抖动,错误会指数级放大。不能等出问题再查。
- 所有 Redis 操作包裹 try-catch,失败时自动 fallback 到数据库查询(非静默失败)
- 用
Cache::get('key', function () { return Db::...; })形式,天然支持降级逻辑 - 接入 Prometheus + Grafana,监控 Redis 的
connected_clients、used_memory_peak、rejected_connections等关键指标 - 在 Swoole 启动脚本中注册
onWorkerError回调,捕获协程内未处理异常并上报



















