客户端打开 gzip 压缩后,所有请求都返回 rpc error: code = Unimplemented desc = grpc: Decompressor is not installed for grpc-encoding "gzip",把压缩关掉就又好了。乍看像缓存或者权限的锅,追下去往往不是。

import _ "google.golang.org/grpc/encoding/gzip"
conn, _ := grpc.Dial(addr,
    grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name)))

追下去是这么回事:grpc-encoding 头里声明了压缩算法,服务端要能查到对应的解压实现。Go 的 grpc 默认只带 identity,gzip 需要显式 import 注册,客户端开了也没用。

「gRPC 压缩协商」这类改动最怕改一半,回滚脚本先准备好,再动生产。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。

能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。报错里带路径的,先去看那个路径在不在、权限对不对。

同一份配置存在多处的,先确认改的是被加载的那一份。新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。

具体做法是,服务端引入 gzip 包并注册 不要只改客户端;确认客户端和服务端支持的算法有交集 协商失败会直接拒绝;压缩级别先用默认值 别为了省带宽把 CPU 打满;用 grpcurl 带 -gzip 参数验证一次。

验收就看一点,带 gzip 的请求返回 200 响应头里 grpc-encoding 是 gzip 不再报 Decompressor not installed。

作者 9823189