根本原因是同步阻塞代码(如sleep、file_get_contents)卡住主Reactor线程;须改用协程函数(co::sleep、Swoole\Coroutine\Http\Client),并在onRequest中显式使用go()启用协程。

为什么 swoole_http_server 启动后没响应?检查事件循环是否被阻塞
常见现象是执行 $server->start() 后控制台卡住、curl 无返回、端口看似监听但连接超时。根本原因不是配置错,而是你写了同步阻塞代码(比如 sleep()、file_get_contents() 或未设超时的 curl_exec())直接挂在主 Reactor 线程里。
实操建议:
- 所有耗时操作必须改用协程函数:用
co::sleep()替代sleep(),用Swoole\Coroutine\Http\Client替代同步 cURL - 确认
onRequest回调里没调用任何非协程安全的扩展函数(如mysqli_query、pdo->query()) - 启动前加日志:
echo "Server starting on http://127.0.0.1:9501\n";,确认是否真卡在start()调用前
如何让 onRequest 正确返回 JSON 而不被 Swoole 自动加 HTML 头?
Swoole 默认把响应体当 text/html 输出,Content-Type 是 text/html,浏览器或 curl 会解析失败。这不是 bug,是设计如此——它不替你决定语义。
实操建议:
- 必须手动设置头:
$response->header('Content-Type', 'application/json; charset=utf-8'); - 注意
$response->end()只接受字符串,别传数组:$response->end(json_encode(['code' => 0], JSON_UNESCAPED_UNICODE)); - 如果用了
set(['http_compression' => true]),确保 JSON 字符串长度 > 20 字节,否则压缩可能失效或报 warning
子进程崩溃导致服务器退出?看 worker_num 和 max_request 怎么配
写错的 PHP 代码(如 undefined index、内存溢出、未捕获异常)会让单个 worker 进程 segfault 或 exit,Swoole 默认会重启该 worker;但如果 max_request 设为 0 或过大,累积的内存泄漏可能最终拖垮整个服务。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
实操建议:
- 开发期设
'worker_num' => 2和'max_request' => 100,便于快速暴露内存/资源泄漏 - 线上环境避免设
max_request = 0,推荐1000–3000,平衡稳定性与 GC 压力 - 务必注册
onWorkerError回调,至少记录$worker_id和$exit_code,否则崩溃无声无息
协程上下文丢失:为什么 go(function () { echo Co::getcid(); }); 在 onRequest 里总输出 0?
这不是协程没启用,而是你误以为 onRequest 自动运行在协程环境里。实际上,Swoole 7.4+ 默认开启协程 Hook,但 onRequest 本身仍是同步回调——它的函数体不在协程中执行,除非你显式 go() 或 defer()。
实操建议:
- 需要协程能力?必须包一层:
go(function () use ($request, $response) { /* 协程内逻辑 */ }); - 别依赖
Co::getcid()判断是否在协程——它返回 0 只代表“当前线程无活跃协程”,不代表不能用协程函数 - 数据库等必须协程化的操作,直接用
Swoole\Coroutine\MySQL,别试图在同步回调里混用 PDO
真正难的不是写通一个 hello world 服务器,而是理解 Swoole 不是“换个 start 方式”的 Apache —— 它把 PHP 拉进了系统级并发模型里,而多数人还在用脚本思维写服务端逻辑。

















