swoole的http/websocket压缩需精细配置:http压缩默认gzip,仅支持gzip/deflate,由http_compression_level(0–9)控制压缩强度与性能平衡;websocket压缩依赖permessage-deflate协商,浏览器支持不一,且仅对文本类mime生效。

开启 Swoole 的 http_compression 或 websocket_compression 后,压缩行为是自动触发的,但实际性能差异几乎全由底层算法和参数决定——不是“开或不开”的问题,而是“用什么、怎么配”的问题。
HTTP 压缩默认用 Gzip,但不等于只能用 Gzip
Swoole 4.8+ 内置的 HTTP 压缩仅支持 gzip 和 deflate(即 zlib),不支持 LZ4/Zstd 等现代算法。它依赖 PHP 的 zlib 扩展,压缩级别由 http_compression_level 控制(默认 1,范围 0–9):
-
http_compression_level = 0:禁用压缩,但依然会检查Accept-Encoding头 -
http_compression_level = 1:最快,压缩率低,适合高频小响应(如 JSON API) -
http_compression_level = 6–9:CPU 开销明显上升,对 >1KB 的 HTML/CSS/JS 有效,但对已压缩资源(如 JPEG、WebP)无效,反而增加延迟
注意:http_compression 仅对响应体生效,且只压缩 text/*、application/json、application/javascript 等白名单 MIME 类型;图片、字体等二进制内容不会被处理。
WebSocket 压缩需手动协商,且默认不启用
WebSocket 的 websocket_compression 是可选扩展(permessage-deflate),开启后需客户端明确支持并协商成功才启用。常见坑点:
- 浏览器 WebSocket 实现对 permessage-deflate 支持不一致(Chrome ≥ 75 支持,Safari 长期不支持)
- 即使服务端设为
true,若客户端未在握手头中带Sec-WebSocket-Extensions: permessage-deflate,Swoole 不会压缩任何帧 - 压缩粒度是每条消息(frame),不是整个连接;小消息(
实测显示:对平均 2KB 的聊天消息,启用后 CPU 使用率上升 12%~18%,但带宽下降约 35%;若消息多为 base64 图片片段,则几乎无收益,还拖慢吞吐。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
自定义压缩更灵活,但也更易出错
绕过 Swoole 内置压缩、改用 PHP 原生函数(如 gzcompress、zstd_compress)或扩展(如 snappy)时,你完全控制时机与条件,但必须自行处理:
- 响应头必须显式设置
Content-Encoding,否则客户端无法解压 - 需判断是否应压缩——例如,
Content-Type: image/svg+xml可压,image/png绝对不能压 - 压缩前要确认数据长度,
gzcompress('')返回空字符串,但某些客户端会因缺失Content-Length而卡住 - 若用 Zstd 或 Snappy,需确保目标环境已安装对应 PHP 扩展,且版本兼容(如
zstd扩展 v0.12+ 才支持流式压缩)
一个典型误用:gzencode($data, 9) 生成的是 gzip 格式(含 header + CRC),而 gzcompress 生成的是 raw deflate 数据——混用会导致客户端解压失败,错误信息常为 ERR_CONTENT_DECODING_FAILED。
压缩收益有硬边界,别迷信“越高压缩越好”
真正影响性能的从来不是“是否压缩”,而是“压缩是否值得”。关键临界点包括:
- 原始响应体
- 文本重复率低(如加密 token、UUID 列表):Gzip 压缩率可能只有 1.05x,Zstd 也难超 1.1x
- 协程密集型服务:每个压缩调用都会短暂阻塞当前协程,
gzcompress在 PHP 7.4 下平均耗时 0.08ms/KB,看似小,但 10K QPS 就是 800ms/s 的纯压缩开销
最常被忽略的一点:Swoole 的内置压缩不支持动态降级。当 CPU 负载 >80% 时,它仍会按配置等级执行压缩——而生产环境中,你更需要的是“负载高时自动切到 level=1 或禁用”,这只能靠自定义中间件 + 系统指标监控实现。










