swoole不是php框架,而是面向生产环境的php异步网络通信引擎;它采用常驻内存设计,支持tcp/udp/http/websocket等协议,基于c扩展实现事件驱动与协程,性能远超传统php-fpm模式。

直接说结论:Swoole 不是 PHP 框架,也不是 Web 开发框架,它是一个面向生产环境的 PHP 异步网络通信引擎。用错定位,后续所有内存、协程、连接管理问题都会放大。
为什么不能把 Swoole 当成 ThinkPHP 或 Laravel 用
Swoole 启动后是常驻内存的,swoole_server 进程不会像 PHP-FPM 那样每次请求完就销毁整个执行环境。这意味着:
-
static变量、global变量、类静态属性(如Test::$cache)会一直留在内存里,不随请求结束而释放 - 闭包中捕获
$this或长生命周期对象,容易形成循环引用,PHP GC 在协程环境下难以及时回收 - 异步客户端(如
swoole_client、swoole_redis)底层有引用计数,unset不等于立即释放,必须等连接close后才减计数
常见错误现象:memory_get_usage() 持续上涨,top 显示 Worker 进程 RSS 占用不断升高,重启后回落 —— 这不是“慢”,是泄漏。
协程里怎么安全用变量和资源
协程不是“自动内存管家”。每个协程退出时,它的局部变量会释放,但以下情况不会:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 通过
use捕获了外部作用域的变量,且该变量本身是对象或数组,又在回调中被持续追加(如$arr[] = $data) - 使用
Swoole\Coroutine\Channel或Swoole\Table存储数据,但没设上限或没定期del/clear - 忘了在协程末尾显式关闭资源:比如
$redis->close()、fclose($fp)、Swoole\Timer::clear($tid)
推荐做法:
- 用
defer做收尾:defer(fn() => $redis->close()); - 大数组/字符串拼接避免写死在
static上,改用Swoole\Coroutine\Channel+ 超时淘汰 - 数据库/Redis 连接优先走连接池,而不是每次 new 一个 client
Worker 进程内存爆掉前还能做什么
靠“自觉清理”不可靠,得有兜底机制:
- 设置
max_request:例如'max_request' => 2000,让 Worker 处理完 2000 个请求后自动退出,进程级内存全量回收 - 配合
reload_async和平滑重启,避免服务中断 - 用
Swoole\Server::stats()或swoole_server->stats()定期采样,监控worker_request_count和memory_usage增长斜率 - 上线前跑压测,观察
ps aux | grep 'php.*worker'的 RSS 是否线性增长
最易被忽略的一点:日志写入、var_dump、未关闭的 fopen('php://memory') 等调试残留,在常驻进程里会越积越多,比业务逻辑泄漏更隐蔽。










