easyswoole 面试重实践而非概念,需掌握协程实际应用与排坑:go() 中禁用 echo/var_dump,须用日志;mysql 必用协程客户端并配置连接池;onrequest 不触发多因协程异常未捕获,需 try/catch + 协程钩子。

EasySwoole 面试不考“协程是什么”,而是考你有没有在线上用过、调过、踩过坑。光背 go()、defer()、Channel 的定义,基本过不了二面。
为什么 go() 启动的协程里不能直接用 echo 或 var_dump
因为 EasySwoole 默认关闭了协程内输出缓冲(output_buffer),且协程调度器接管了标准输出流。直接 echo 会触发 Swoole\Error: output buffer is disabled 错误,或静默丢弃内容。
- 调试时改用
Logger::getInstance()->log()写日志,别依赖终端回显 - 若需临时打印,先调用
Swoole\Coroutine::set(['output_compression' => false])(仅限开发环境) - 切记:线上禁用任何
print_r/var_dump,它们不是协程安全的,可能阻塞当前协程甚至污染其他协程的输出缓冲
MySQL 连接在协程里复用失败,报 Connection lost
根本原因不是连接超时,而是你用了原生 PDO 或 mysqli —— 它们不是协程友好的,底层 socket 不受 Swoole 协程 Hook 管理。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 必须换用
Swoole\Coroutine\MySQL或 EasySwoole 封装的DbManager - 连接池配置要显式开启:确保
maxIdle和maxActive不为 0,否则每次new都新建连接,压测时秒变连接风暴 - 事务中不要跨协程:一个
go()里开启事务,另一个go()里提交,会报There is no active transaction—— 协程间不共享数据库上下文
HTTP 请求进来了,但 onRequest 没触发,日志也没报错
大概率是协程异常未被捕获,导致当前协程静默退出,而 Swoole 默认不会把协程 panic 上抛到主循环。现象就是请求卡住、超时、或直接 502。
- 检查所有
go()块是否包了try/catch,尤其注意Redis::connect()、Http\Client调用 - 启用协程错误追踪:
Swoole\Coroutine::set(['hook_flags' => SWOOLE_HOOK_ALL])并配合Co\Run日志开关 - 别在
__construct或initialize()里做阻塞操作(比如同步读配置文件),这些代码运行在主协程,一旦 hang 住,整个 worker 就卡死
协程不是银弹,它把“哪里阻塞”从函数调用栈里抹掉了——你得靠日志 + Coroutine::listCoroutines() + strace 组合定位,而不是盯着 go() 数量看。










