ThinkPHP高并发优化需从PHP运行时、数据库、缓存、异步四层拆解:OPcache预加载+static模式FPM实现常驻;PDO长连接+Redis缓存+连接健康探测防耗尽;禁用文件缓存改用带版本前缀的Redis防穿透;日志短信等非核心逻辑必须队列异步化。

ThinkPHP 高并发不是靠堆配置硬扛,而是从请求进来的第一毫秒开始拆解瓶颈——PHP 运行时是否常驻、数据库连接是否被反复创建、缓存是否在抢同一个文件锁、非核心逻辑是否卡住主线程。真正有效的优化,是让每个环节都“不等、不争、不重复”。
PHP-FPM 与 OPcache 必须协同预热
只开 opcache.enable=1 不够,冷启动仍慢;只设 pm.max_children=200 更危险——内存爆掉比 QPS 低更致命。
- 写好 preload.php,用 require_once 显式加载
think/App.php、think/Container.php、路由定义和核心配置,禁止调用 DB 或业务逻辑 - opcache.memory_consumption 设为 512(MB),opcache.validate_timestamps=0(上线后可改回 1)
- FPM 改用 static 模式:
pm = static,pm.max_children = 64(8GB 内存服务器参考值),pm.max_requests = 0 - 验证是否生效:运行
php -v看是否有 “with Zend OPcache”,再执行opcache_get_status()['preload_statistics']['scripts']确认数量 > 0
数据库连接必须“省着用、稳着拿”
ThinkPHP 没有原生连接池,MySQL 的 max_connections 很快耗尽,报错 SQLSTATE[HY000] [1040] 就是信号。
- 启用 Swoole 连接池(TP6+):
'pool_size' => 200(建议 CPU 核数 × 25),配'pool_get_timeout' => 3防卡死 - 禁用读写分离(
'deploy' => 0)除非真需要,否则额外连接开销反而拖累 - PDO 强制长连接:
'params' => [\PDO::ATTR_PERSISTENT => true],同时 MySQL 调大wait_timeout - 事务务必短平快,避免
Db::transaction()包裹耗时操作;查前加Db::connect()->query('SELECT 1')主动探测连接有效性
缓存体系要分层、带版本、防穿透
默认的 file 缓存驱动在高并发下会因文件锁排队,所有请求等一个 cache 文件——这不是缓存,是阻塞。
立即学习“PHP免费学习笔记(深入)”;
- 立刻切到 Redis 驱动:
'type' => 'redis',Redis 配置maxmemory-policy allkeys-lru - key 必须含业务前缀 + 版本号:
user:profile:v2:12345,结构一变就换 v3,避免脏数据 - 空结果也得缓存,但过期时间要短:
Cache::remember($key, 60, $callback),防穿透 - 批量写别用循环
Cache::set(),改用Redis::handler()->mset($data)原生命令
非核心逻辑必须异步剥离
日志记录、短信发送、统计上报这些操作,绝不该堵在用户请求链路里——它们慢一秒,接口就多等一秒。
- 识别非实时路径:用中间件或控制器内判断,把耗时操作封装成任务对象
- 投递到队列:
think-queue+ Redis 或直接用 Swoole 协程消费 - 避免 session 文件锁:
session.driver = redis,或在不需要时显式关闭:session_write_close() - 模板、路由、配置缓存全部生成:
php think optimize:config、php think optimize:route、php think optimize:schema



















