swoole 5.1 默认启用协程,i/o 操作天然挂起,须用协程客户端或 go() 启动子协程;swoole-cli 是强制部署标准,静态编译无依赖;worker_num 建议设为逻辑核数×1.5,max_coroutine 更影响吞吐;usr1/usr2 信号语义收紧,需分步热重启。

协程写法别再套回调了,go() 是默认动作
PHP 开发者从 Ratchet 或传统 Swoole 4.x 迁移过来,最常卡在“为什么 onMessage 里不能直接 sleep() 或查数据库”——Swoole 5.1 的协程已默认启用,所有 I/O 操作(MySQL、Redis、HTTP 请求)天然支持协程挂起,无需手动 yield 或嵌套 defer。
- 错误写法:在
onMessage回调里用mysqli_query()或file_get_contents()—— 会阻塞整个 worker - 正确做法:直接调用协程版客户端,比如
Swoole\Coroutine\MySQL或Co\Http\Client,或直接go(function () { ... })启动子协程 - 注意:
usleep()在协程中仍会阻塞,必须换成co::sleep(0.1)(单位秒) - PHP 8.4 下协程调度更稳定,但若混用
pcntl_fork()或dl(),会直接崩溃——Swoole 5.x 已彻底移除dl()支持
swoole-cli 不是可选项,是新部署标准
你写的 Swoole 服务如果还靠 php server.php 启动,说明没跟上 Swoole 5.0 的运行模式变革。swoole-cli 不是“另一个命令行工具”,而是专为 Swoole 场景裁剪的静态 PHP 运行时,它把 libc、openssl、curl 全部静态链接,连 glibc 版本差异都不用操心。
- 旧方式:
php -d extension=swoole.so server.php→ 依赖系统环境、扩展加载顺序、php.ini 配置 - 新方式:用
swoole-cli编译打包后得到单文件二进制,./myapp直接运行,无任何外部依赖 - 构建时必须显式声明所需扩展,比如
--enable-mysqlnd,否则Co\MySQL会报Class not found - 不支持
extension=xxx.so动态加载,也不读取php.ini—— 所有配置得通过--ini参数传入或代码内ini_set()
worker_num 和 task_worker_num 别乱设,CPU 核心数不是唯一依据
很多人照抄文档写 'worker_num' => 8,结果高并发下内存暴涨、连接超时——Swoole 5.x 的内存管理重构后,每个 worker 协程栈默认 2MB,8 个 worker 就占掉 16MB 基础内存,还没算 Redis/MySQL 连接池。
-
worker_num建议设为 CPU 逻辑核数 × 1.5(非 ×2),尤其在混用 HTTP + WebSocket 场景下,避免因长连接挤压短请求资源 -
task_worker_num不要盲目设高;Swoole 5.x 的 task 进程改用共享内存通信,但每个 task 进程仍独占堆内存;IO 密集型任务(如发短信、写日志)建议 ≤ 4 个,计算密集型才考虑提升 - 真正影响吞吐的是
max_coroutine(默认 3000),它限制单 worker 最大协程数;压测时先调这个,比加 worker 更有效 - 用
swoole_server->stats()查看connection_count和tasking_num,比看 CPU 使用率更能定位瓶颈
热重启信号变了,USR1 和 USR2 行为要重验
Swoole 5.x 对信号处理做了语义强化:kill -USR1 现在只重启 worker 进程,不再顺带 reload task 进程;kill -USR2 也只重启 task 进程,且会等待当前 task 执行完才退出旧进程——这和旧版“暴力 kill 再拉起”完全不同。
- 如果你的部署脚本还用
kill -USR1 $(cat master.pid)期望同时更新 worker + task 逻辑,现在会漏掉 task 代码热更 - 新版推荐分两步:先
kill -USR2更新异步任务逻辑,再kill -USR1更新主服务逻辑 -
onWorkerStart和onTaskStart回调里不能做耗时初始化(如加载大配置文件),否则热重启会卡住;应改用协程懒加载或onManagerStart预热 - 务必验证
onWorkerStop是否被触发——Swoole 5.x 在优雅退出时保证该回调执行,但若你在里面用了同步 MySQL 写操作,可能超时被强制终止
swoole-cli 必须静态编译、信号语义收紧——这些都不是为了增加复杂度,而是让高并发场景下的行为更可预测。真正在生产跑稳,关键不在会不会用新 API,而在敢不敢删掉那些“看似有用”的兼容层代码。










