完整课程入口:996 全套课程体系 | Lua 学习路径 | 幂尔框架 mirs.cn
排行榜快照、批量邮件列表、配置下发这类大消息,传输体积直接影响带宽与延迟。gzip 压缩能显著缩小体积,但压缩本身有 CPU 成本——不是所有消息都该压。阈值策略:体积超过设定值才启用压缩,小消息保持原样。适用于一切"大块文本/结构化数据"的传输场景。
local COMPRESS_THRESHOLD = 2048 -- 2KB 以上才压缩
local function sendWithCompression(cmd, body)
if #body >= COMPRESS_THRESHOLD then
local compressed = zlib.deflate(body)
conn:send(packHeader(cmd, #compressed, 1)) -- 标志位 1 = 已压缩
conn:send(compressed)
else
conn:send(packHeader(cmd, #body, 0)) -- 标志位 0 = 原样
conn:send(body)
end
end
协议头里加 1 个字节的压缩标志位,接收端按标志位解压或直读。阈值 2KB 的依据:gzip 对小于 2KB 的文本压缩率通常不足 30%,收益抵不过 CPU 与额外的解压延迟。
三类消息的压缩收益(LuaJIT + zlib 绑定):排行榜快照 86KB → 19KB(压缩率 78%,压缩耗时 3.1ms);批量邮件列表 24KB → 6KB(75%,1.2ms);聊天消息 300B → 320B(负收益,不压缩)。传输耗时按 5Mbps 带宽折算:86KB 快照原样传输 138ms,压缩后 30ms + 3.1ms 压缩 = 净省 100ms 以上。体积越大、结构重复度越高,压缩收益越大——JSON 这类高冗余格式尤其明显。
压缩与加密的顺序:先压缩后加密(密文不可压缩,顺序反了压缩失效)。CPU 保护:压缩集中在发送线程的空闲时段执行,或限制每秒压缩总量,防止突发大消息推高 CPU。级别选择:zlib 压缩级别 1(最快)与 9(最小)的体积差通常只有 5~10%,游戏传输选级别 1~3,追求最小体积的归档场景才用高级别。阈值与级别写入配置,联调期可调优。
压缩标志位要在协议文档里登记,接收端按标志位分支处理。跨版本兼容期(新老客户端并存)双格式都要能解析,切换完成后旧格式保留一个版本的兼容期再下线,这是协议演进的通用做法。