thinkphp6万并发需五层协同优化:php-fpm调参(如pm.max_children=64)、关闭debug与日志、数据库启用持久连接并禁用读写分离、缓存与session切redis、非实时逻辑全入队列。

ThinkPHP6 本身不支持协程或异步非阻塞模型,一万并发下内存溢出不是配置调大就能解决的问题——核心矛盾在于同步阻塞架构 + 默认行为堆叠(如调试日志、全量查询、文件Session、未复用连接),导致每个请求内存占用高、响应慢、连接堆积。必须从 PHP 运行层、框架配置、数据库交互、缓存与队列五个层面协同优化。
PHP-FPM 与内存配置调优
默认 pm.max_children=50 完全无法支撑万级并发,盲目拉高会直接耗尽服务器内存。合理做法是:
- 设 pm = static 或 pm = dynamic,根据 4核8G 服务器建议:
pm.max_children = 64,pm.start_servers = 32,pm.min_spare_servers = 16,pm.max_spare_servers = 48 - 每个 worker 内存需压到 20MB 以内:关闭
app_debug = false,禁用trace和 SQL 日志,删掉 runtime/log 下所有日志文件 - CLI 命令(如队列消费)单独调高内存:
php -d "memory_limit=512M" think queue:work,避免和 Web 请求争资源
数据库连接与查询瘦身
MySQL 的 max_connections 默认常为 151,万并发下极易触发 Too many connections。TP6 没有连接池,只能靠复用+精简:
- 数据库配置中启用持久连接:
'params' => [PDO::ATTR_PERSISTENT => true],并同步调大 MySQL 的wait_timeout(建议 300 秒) - 禁用读写分离(
'deploy' => 0),除非你已部署独立从库且做了中间件精准路由 - 避免在循环里查库:
foreach ($ids as $id) { Db::table('log')->find($id); }改为Db::table('log')->whereIn('id', $ids)->select() - 导出或统计类任务禁用
chunk(),改用生成器 +where('id', '>', $lastId)游标分页,内存恒定在几百 KB
缓存与 Session 必须切换驱动
默认的 file 缓存和 file Session 是万并发下的性能杀手——文件锁会让所有请求排队等待单个 cache 文件或 session 文件。
- Session 改用 Redis:
'type' => 'redis',并设置'use_trans_id' => true防止会话劫持 - 缓存统一走 Redis:
Cache::store('redis')->get('key'),避免Cache::get()走默认 file 驱动 - Redis key 设计要带业务前缀和过期时间,例如
user:profile:12345:202608,TTL 控制在 3600 秒内,防雪崩
非实时逻辑全部丢进队列
登录记录、消息通知、数据同步等操作,不能在 HTTP 请求链路中同步执行。否则一个请求卡住,整个 worker 就被占着不动。
- 使用 ThinkPHP 自带的
think-queue,驱动选 Redis(比 database 更快更稳) - 控制器中只发任务:
Queue::push('app\job\SendNoticeJob', ['uid' => $uid, 'msg' => $text]) - 队列进程单独部署:
php think queue:work --daemon --queue=notice --delay=0 --sleep=3,配合 supervisor 管理 - 关键任务加失败重试(
attempts(3))和延迟投递(delay(60)),避免瞬时洪峰打垮下游服务
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











