open_http2_protocol必须显式设为布尔值true,不能是字符串或数字;且需配合SWOOLE_SOCK_TCP|SWOOLE_SSL、有效PEM证书及编译时启用--enable-http2和--enable-openssl。

open_http2_protocol 必须显式设为 true,且不能是字符串或数字
这个配置不是开关“默认开启”,也不是靠环境自动识别——它必须在 $server->set() 里写成布尔值 true。写成 "true"、1 或 "on" 都无效,Swoole 会静默忽略,连 warning 都不报。
常见错误现象:curl 加了 --http2 却返回 HTTP/1.1 响应头;浏览器访问 https 站点,ALPN 协商失败,连接直接断开。
-
open_http2_protocol => true是唯一合法写法 - 该参数只影响协议解析层,不改变 socket 类型或证书加载逻辑
- 即使其他所有条件都满足,只要这里写错,HTTP/2 就不会启用
SSL/TLS 是硬性前提,SWOOLE_SOCK_TCP|SWOOLE_SSL 缺一不可
HTTP/2 在 Swoole 中不支持明文 h2c(即非 TLS 的 HTTP/2),这不是可选配置,而是协议强制要求。用纯 TCP 启动 HTTP/2 服务,swoole_server->start() 可能卡住、无日志、或报 ssl handshake failed。
正确写法必须是:
$server = new Swoole\Http\Server('0.0.0.0', 443, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
-
ssl_cert_file和ssl_key_file路径必须指向可读 PEM 文件 - 私钥不能有密码保护,否则启动时会阻塞或抛出
SSL_CTX_use_PrivateKey_file failed - 开发可用自签名证书,但需手动信任;生产环境必须用可信 CA 签发
编译时没开 --enable-http2 和 --enable-openssl,运行时配置全白搭
哪怕 PHP 代码里把所有参数写对,如果 Swoole 扩展本身没编译进 HTTP/2 支持,open_http2_protocol => true 就只是个摆设,控制台只会输出一句警告:http2 protocol is not supported,然后继续跑 HTTP/1.1。
检查方法:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
php --ri swoole
输出中必须同时包含:
http2 => enabledopenssl => enabled
常见遗漏点:
- Ubuntu/Debian 用户漏装
libnghttp2-dev,导致编译时--enable-http2自动失效 - 升级 Swoole 后没重编译,旧版本(如 v4.8.0 之前)ALPN 支持不完整,握手失败但无明确提示
- 用 pecl install 安装时没交互确认
enable http2 support? [no]这一项
客户端不协商,服务端开了也收不到 HTTP/2 请求
开启 open_http2_protocol 后,Swoole 只是“能解析”HTTP/2 帧,并不会主动把 HTTP/1.1 请求升级过去。是否走 HTTP/2,完全取决于客户端是否发起 ALPN 协商(HTTPS 场景)或发送 Upgrade: h2c(明文场景,已被主流浏览器禁用)。
调试建议:
- 浏览器访问:必须用
https://,且服务端证书有效、ALPN 返回h2,才能触发 - curl 测试:加
--http2(自动协商)或--http2-prior-knowledge(跳过 ALPN 直连) - 注意:HTTP/2 下
timeout控制的是整个流生命周期,不是单请求耗时;LLM 流式响应首 token 慢时,必须同步调大timeout,否则连接会被静默中断
最容易被忽略的是证书私钥权限和格式——即使所有配置都对,ssl_key_file 若是 PKCS#8 格式、或属主不对、或权限不是 600,Swoole 进程就无法读取,也不会报错,只表现为连接超时或空响应。

















