thinkphp6高并发需用swoole或workerman替代php-fpm;官方扩展think-swoole/think-worker已封装生命周期隔离,须配置连接池、禁用file缓存、正确设置反代与日志路径。

ThinkPHP6 本身是同步阻塞框架,原生不支持长连接、协程或异步 I/O。要真正提升高并发能力(比如扛住 1000+ 并发请求),必须脱离 PHP-FPM 模式,用 Swoole 或 Workerman 替换底层服务器。两者都能用,但选哪个、怎么接、哪块最容易崩——得看你的实际场景。
为什么不能直接在 TP6 里 `new SwooleHttpServer()` 就完事?
能启动,但大概率会出问题:TP6 的生命周期(App 初始化、中间件、路由解析、数据库连接池)默认依赖 PHP-FPM 的“一次请求、一次销毁”模型。而 SwooleHttpServer 是常驻内存的,全局变量、静态属性、单例对象不会自动重置。
常见错误现象:
- 数据库连接复用失败,报
MySQL server has gone away - Session/Cache 在不同请求间污染(比如用户 A 登录后,用户 B 请求拿到 A 的 session 数据)
- 日志写错文件、配置被上一个请求改掉
实操建议:
- 不要手写裸
SwooleHttpServer+ 手动调用App::invokeMethod(),容易漏掉钩子(如onWorkerStart中重置 DB 连接池) - 优先使用官方扩展
topthink/think-swoole(Swoole 方向)或topthink/think-worker(Workerman 方向),它们已封装好生命周期隔离逻辑 - 务必关闭 TP6 的
app_debug和所有调试中间件(如 Trace、Log 写文件),否则常驻进程下日志爆炸、磁盘打满
think-swoole 和 think-worker 启动方式差异在哪?
表面都是 php think xxx,但背后模型完全不同:
-
think-swoole启动的是Swoole\Http\Server实例,支持协程、异步 MySQL/Redis、HTTP/WS 协议混用,适合需要毫秒级响应、大量 IO 等待(如调第三方 API、查 Redis)的场景 -
think-worker启动的是Workerman\Worker实例,基于多进程 + 事件循环,无协程,但代码完全同步风格,对老项目迁移更友好,也更适合 WebSocket 长连接广播类业务
-
think-swoole的worker_num建议设为 CPU 核数(如 2 核就设 2),协程数靠max_coroutine控制(默认 3000,够用) -
think-worker的count是进程数,建议设为 CPU 核数 × 2(如 2 核设 4),它不自动扩容,超载就丢包 - 两者都必须在
config/worker.php或config/swoole.php中显式配置host和port,别依赖默认值(0.0.0.0:9501可能被防火墙拦)
'http' => ['host' => '0.0.0.0', 'port' => 8080];而 Workerman 的 socket 配置必须写成 'socket' => 'http://0.0.0.0:8080',少个 http:// 就直接启动失败,报错信息是 Invalid socket address。
数据库和 Redis 怎么不崩?关键就在这三行配置
TP6 默认用 PDO,但在常驻进程中会复用连接,导致超时断连或事务残留。这不是 Bug,是设计使然。
实操建议:
- MySQL 必须启用
pool:在config/database.php中加'deploy' => 1和'pool' => ['min' => 2, 'max' => 16],否则 1000 并发时大概率卡死在PDO::__construct - Redis 若用
topthink/think-redis,需确认驱动是Swoole\Coroutine\Redis(Swoole 下)或Predis\Client(Workerman 下),不能混用;Swoole 场景下,redis.connect_timeout建议设为0.5,避免协程卡住 - 所有
new \think\Cache()或Cache::store()调用,必须确保 store 驱动支持长连接(如redis或memcached),禁用file驱动——它在常驻进程下会疯狂锁文件
think-swoole 默认启用协程 MySQL,但如果你手动 new PDO(),就绕过了协程封装,IO 仍会阻塞整个 worker 进程。
上线前必做的三件事:端口、信号、日志
本地跑通 ≠ 上线可用。很多团队卡在部署环节:
- 宝塔面板用户注意:
think-swoole和think-worker启动的服务**不走 Nginx 转发**,必须把域名直接反代到你的8080(或自定义)端口,并在 Nginx 配置中加proxy_http_version 1.1;和proxy_set_header Upgrade $http_upgrade;(WebSocket 必需) - Linux 下必须用
nohup php think swoole start &或systemd管理进程,别直接前台运行——SSH 断开就挂了;think-worker支持php think worker restart,但think-swoole的 reload 命令只重启 worker,master 进程不变,有配置更新必须stop再start - 日志路径必须绝对且可写:
runtime/log/swoole.log这种相对路径在常驻进程中会错乱,统一写成/www/wwwroot/myapp/runtime/log/swoole.log
daemonize 设为 true 后,stdout 和 stderr 会被重定向到 /dev/null,所有 var_dump、echo 全消失——调试只能靠日志,别指望终端输出。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











