Go 语言需手动集成 HTTP 响应压缩,常用 gzip 中间件包装 handler,检查 Accept-Encoding、设 Content-Encoding/Vary 头,跳过小响应(≥1KB)及不可压缩类型;Brotli 更优但需第三方库;需协同 HTTP/2、CDN 与缓存策略。

Go 语言原生 net/http 包支持 HTTP 响应压缩,但默认不启用。要减少网络传输开销,需手动集成 gzip(或 zlib、br)压缩逻辑,核心在于拦截响应体、压缩内容、设置正确 Header,并兼顾客户端兼容性与性能开销。
启用 Gzip 压缩中间件
最常用方式是用中间件包装 http.Handler,在写入响应前检查 Accept-Encoding 并动态压缩。推荐使用标准库的 gzip 包,无需第三方依赖:
- 创建一个实现了
http.ResponseWriter接口的 wrapper,重写WriteHeader和Write方法 - 在
WriteHeader中判断客户端是否支持gzip(检查r.Header.Get("Accept-Encoding")) - 若支持且状态码为 2xx,初始化
gzip.Writer并替换原始ResponseWriter - 压缩后设置
Content-Encoding: gzip和Vary: Accept-Encoding头
避免压缩小响应或不可压缩内容
压缩极小响应(如 JSON 短响应、空响应)反而增加 CPU 开销且可能变大。建议设置阈值(如 ≥ 1KB)再启用压缩:
- 在 wrapper 中缓存写入内容到 bytes.Buffer,达到阈值后再启动 gzip.Writer
- 跳过已知不可压缩类型:
image/*、application/octet-stream、font/*等 - 优先检查
Content-Type,对text/html、application/json、text/css、application/javascript等文本类型启用压缩
支持 Brotli(br)提升压缩率
Brotli 比 gzip 压缩率更高、解压更快,现代浏览器广泛支持。Go 标准库不内置 brotli,但可用 github.com/andybalholm/brotli:
立即学习“go语言免费学习笔记(深入)”;
- 中间件中同时解析
Accept-Encoding,按br>gzip> none 优先级选择算法 - 注意 brotli 的压缩级别和缓冲区配置(如
br.NewWriterLevel(w, 4)),平衡速度与体积 - 确保
Content-Encoding和Vary头准确反映实际编码方式
配合 HTTP/2 与缓存策略使用
压缩效果受协议与缓存影响,需协同优化:
- HTTP/2 自带 HPACK 头压缩,但响应体仍需 gzip/br;无需额外配置,压缩中间件照常生效
- 若使用 CDN 或反向代理(如 Nginx),确认它未重复压缩或覆盖
Content-Encoding - 压缩后响应应设
Cache-Control: public, must-revalidate,但注意不同编码版本需独立缓存(Vary: Accept-Encoding是关键)
不复杂但容易忽略。关键是让压缩逻辑透明、可控、可退化,而不是一刀切开启。










