腾讯云swoole开发岗面试重实战:协程必须开启hook(swoole\runtime::enablecoroutine(swoole_hook_all)),mysql需用连接池并显式close,禁用静态变量防内存泄漏,max_request对协程无效须手动清理资源。

腾讯云Swoole开发岗面试不考概念背诵,只看能不能在真实长连接、高并发、常驻内存场景下写出不出错的代码。核心就三点:协程用对没、内存没爆没、IO没卡死没。
协程启动前必须调用 Swoole\Runtime::enableCoroutine()
这是最常被跳过的一步。没开 Hook,file_get_contents、curl_exec、sleep 这些原生函数依然阻塞整个进程,协程根本“协”不起来。
- 必须在 Server 启动前(如
onWorkerStart或脚本最顶部)调用,不能在协程内再调; - 建议传参数
SWOOLE_HOOK_ALL,避免漏掉某些扩展(比如 PDO 默认不被 Hook); - 开启后,所有支持协程的客户端(如
Swoole\Coroutine\MySQL)才能真正异步,否则会退化成同步串行; - 常见错误现象:
go(function () { sleep(3); });执行完发现整个 Worker 卡住 3 秒——就是没开 Hook 的典型表现。
Swoole\Coroutine\MySQL 必须搭配连接池使用
直接 new 一个 Swoole\Coroutine\MySQL 实例并复用,等于把连接绑死在一个协程里,不仅无法复用,还可能因超时或异常导致连接泄漏。
腾讯云通用文字识别(高精度版)技能包。用户发送/粘贴图片、提供图片URL或要求识别图片文字时自动调用。支持中文、英文、中英混合、数字及特殊符号的检测与识别,返回文字框位置与内容。适用于文字较多、版式复杂、准召率要求高的场景。
- 正确做法是用
Swoole\Coroutine\Pool封装,或更推荐使用 Swoole 官方推荐的mysql://DSN +Swoole\Coroutine\MySQL\Pool; - 连接池需设置
min_connections和max_connections,避免空闲连接过多占用内存,也防止突发流量打满连接数; - 每次使用后必须显式
$mysql->close()(或让对象自动销毁),否则连接不会归还池中; - 注意:PDO 不支持协程,即使开了 Hook,
PDO::query()仍会阻塞,必须换掉。
全局变量和静态属性是内存泄漏重灾区
Swoole Worker 进程不死,static $cache = []、global $config、闭包里引用的外部大数组,都会一直留在内存里,每处理一次请求就涨一点,直到 OOM。
- 所有请求级数据必须用局部变量,禁止写进类静态属性或函数 static 变量;
- 如果真要缓存,用
swoole_table或swoole_atomic等进程安全结构,并配好 TTL 清理逻辑; -
$GLOBALS、$_SERVER、$_ENV在协程间共享,修改它们等于污染其他协程上下文; - 用
memory_get_usage(true)在onRequest前后打点,比盲猜更早发现增长趋势。
max_request 对协程 Server 无效,别依赖它保命
很多开发者以为设了 'max_request' => 3000 就能兜底,但这是 FPM 模式下的机制。Swoole 的 SWOOLE_PROCESS 或 SWOOLE_BASE 模式下,这个配置完全不生效。
- 真正有效的方案只有两个:一是用
onWorkerStop手动清理资源(如关闭未释放的 Redis 连接、unset 大数组); - 二是配合
opcache.restrict_api+ 定期 reload Worker(通过kill -USR1),但 reload 期间有请求丢失风险; - 更务实的做法是:把每个请求的生命周期控制在局部作用域,不依赖进程重启来“擦屁股”;
- 最容易被忽略的一点:协程里
throw未被捕获,会导致该协程栈不释放,相关变量持续驻留——务必加try/catch包裹业务逻辑。










