Go标准库仅原生支持gzip,brotli需引入第三方包github.com/andybalholm/brotli;gzip零依赖、低延迟、适合高频小响应,brotli压缩率高但耗CPU、仅在≥1MB且低频场景才具优势;HTTP传输必须依Accept-Encoding协商并设置Vary头,否则引发缓存污染。

Go标准库只原生支持gzip,brotli需第三方包
Go的net/http和compress/gzip包开箱即用,但compress/brotli不在标准库中。你必须显式引入github.com/andybalholm/brotli(目前最稳定、被Drogon/Fiber等项目验证过的实现)。这意味着:
- gzip零依赖、无编译风险、go build直接通过
- brotli会增加构建时间、可能触发CGO(若使用C绑定版)、且需确保运行时动态库可用(如libbrotlidec1)
- 若你用UPX或pkg打包二进制,brotli依赖会让最终体积增大约200–300KB(静态链接时)
gzip压缩快、解压快,适合高频小响应
对单次100KB–500KB的JSON或HTML字符串,gzip在Go中表现更均衡:
- gzip.NewWriterLevel(w, gzip.BestSpeed)能在0.5–2ms内完成压缩(实测i7-11800H)
- 解压几乎无感知,gzip.NewReader(r)延迟稳定在0.1–0.3ms
- 内存占用低:gzip.Reader默认仅用32KB缓冲区,适合高并发连接场景
- 错误处理简单:io.ErrUnexpectedEOF和gzip.ErrHeader覆盖绝大多数边界情况
brotli压缩率高但耗CPU,大字符串才值得上
只有当原始字符串≥1MB且传输频次低(如配置下发、离线包推送),brotli的优势才明显:
- 同一2.1MB HTML字符串,brotli.BrotliWriter{Quality: 6}压缩后为480KB,比gzip.BestCompression(590KB)小18%
- 但压缩耗时翻倍:从8ms升至17ms,CPU使用率峰值高35%
- 解压虽快(0.4ms vs 0.3ms),但首次调用brotli.NewReader会触发字典初始化,有~0.2ms抖动
- 注意Quality参数范围是0–11,0不是“不压缩”,而是最快模式(类似gzip.BestSpeed)
HTTP传输时必须协商Accept-Encoding,不能硬编码
Go的http.ResponseWriter不自动识别客户端是否支持brotli。你得手动检查请求头:
- 错误写法:w.Header().Set("Content-Encoding", "br") + 直接写brotli流 → IE、旧Android WebView会直接崩溃
- 正确流程:
- 解析
r.Header.Get("Accept-Encoding"),按权重提取br、gzip、deflate - 优先选
br(如果服务端已启用且客户端声明支持) - fallback到
gzip,最后才是明文 - 记得设置
w.Header().Set("Vary", "Accept-Encoding"),否则CDN可能缓存错版本
这个逻辑容易漏掉Vary或权重解析(比如br;q=0.8,gzip;q=1.0应选gzip),线上出过多次缓存污染事故。
真正卡住人的不是算法本身,而是br和gzip共存时的Vary头一致性、CDN缓存键设计、以及brotli Writer在panic recover后未关闭导致的goroutine泄漏——这些细节比选哪个算法重要得多。



















