swoole 5 http长连接复用需四维协同调优:协议层确保http/1.1 keep-alive就绪;连接池按吞吐设max_size、min_idle及max_idle_time;双控空闲寿命(timeout+requests限流);通过validate_on_borrow心跳探活、错误日志与prometheus监控防泄漏。

要让 Swoole 5 的 HTTP 服务真正发挥长连接复用优势,不能只开 keepalive,得从协议支持、连接池配置、超时控制、健康检查四方面协同调优。
确保 HTTP/1.1 + Connection: keep-alive 协议就绪
Swoole v5.1+ 的 swoole_http_server 默认启用 HTTP Keep-Alive,但需确认两点:
- 响应头中必须显式包含
Connection: keep-alive(v5.1 默认已加,无需手动 setHeader) - 避免客户端主动发送
Connection: close干扰复用;可在 on('request') 中检查并忽略该头 - 若前端有反向代理(如 Nginx),需确保它也透传 keep-alive 头,且自身
keepalive_timeout≥ 后端 Swoole 值
合理设置连接池大小与复用粒度
Swoole 自身不内置“HTTP 客户端连接池”,但你的服务若需频繁调用下游(如 API、Redis、MySQL),必须在协程内使用连接池库(如 swoole/coroutine-pool 或 hyperf/pool),关键参数如下:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- pool_max_size:按下游单实例吞吐定。例如 MySQL 单实例稳扛 500 并发,建议设为 300~400(留 20% 余量)
- min_idle_size:保持 20%~30% 连接常驻空闲,避免冷启动抖动
-
max_idle_time:设为 60 秒,略小于下游服务的
wait_timeout(如 MySQL 默认 28800 秒,此处不冲突;但 Redis 默认 0,需设为 300 秒防断连) - 每个协程应独立获取/归还连接,严禁跨协程持有连接
双控空闲连接寿命:timeout + requests 限流
仅靠空闲超时不够,单连接长期复用可能因上下文污染或内存累积引发异常。Swoole 虽无原生 keepalive_requests,但可通过业务层模拟:
- 在连接池归还逻辑中,记录该连接已服务请求数;达到阈值(如 1000 次)后主动 close 并新建
- 设置
keepalive_timeout = 30(单位秒),写在$server->set()中,确保小于下游服务的保活时间 - 配合内核 TCP keepalive 探测:调整
net.ipv4.tcp_keepalive_time=60,防止 NAT 或防火墙静默断连
防泄漏与兜底:心跳 + 健康检查 + 日志可观测
长连接复用最大的风险是“假活跃”——连接在池中看似可用,实则已被对端关闭:
- 启用连接池的
validate_on_borrow = true,每次出池前执行轻量探活(如 RedisPING、MySQLSELECT 1) - 对 HTTP 下游,可在请求前加
co::sleep(0)触发协程调度,再尝试getpeername()判断 socket 是否有效 - 开启
log_level => SWOOLE_LOG_WARNING,捕获Connection reset by peer类错误,用于定位泄漏点 - 定期统计连接池中 idle / active / broken 连接数,接入 Prometheus 监控










