Go语言gRPC API:如何查看响应压缩的追踪日志并验证压缩状态?
验证gRPC响应内部压缩的方法
你已经为gRPC API启用压缩,但当前的一元拦截器只监控了请求端的压缩编码(grpc-encoding),无法直接看到响应的压缩处理情况。下面是几种能验证响应是否完成压缩的方案:
1. 开启gRPC Go内置调试日志
通过环境变量开启gRPC的详细日志,就能直接看到内部压缩处理的细节:
export GRPC_GO_LOG_VERBOSITY_LEVEL=99 export GRPC_GO_LOG_SEVERITY_LEVEL=info
启动服务后,日志中会出现类似以下的条目,明确显示响应是否被压缩、压缩前后的字节数:
INFO: [core] [Server #1 Stream #1] Sending message with compression "gzip"
INFO: [core] [Server #1 Stream #1] Compressed message from 1234 bytes to 567 bytes
2. 修改拦截器追踪响应压缩信息
gRPC服务器端的响应压缩状态不会直接暴露在拦截器的返回值里,但可以通过检查上下文关联的压缩器或响应元数据来追踪。修改你的拦截器如下:
import ( "time" "google.golang.org/grpc" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" "google.golang.org/grpc/compressor" "go.uber.org/zap" ) func loggingUnaryInterceptor(ctx goContext.Context, logger *log.LogWrapper) grpc.UnaryServerInterceptor { return func( ctx goContext.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, ) (interface{}, error) { start := time.Now() p, ok := peer.FromContext(ctx) if ok { logger.Infow(ctx, "Request received", zap.String("method", info.FullMethod), zap.String("peer", p.Addr.String()), ) } md, ok := metadata.FromIncomingContext(ctx) if ok { enc := md.Get("grpc-encoding") compression := "none" if len(enc) > 0 { compression = enc[0] } logger.Infow(ctx, "Request metadata", zap.String("compression", compression)) } resp, err := handler(ctx, req) // 新增:检查响应压缩情况 // 查看客户端支持的压缩格式 if respMD, ok := metadata.FromOutgoingContext(ctx); ok { if acceptEnc := respMD.Get("grpc-accept-encoding"); len(acceptEnc) > 0 { logger.Infow(ctx, "Response metadata", zap.String("accepted_compression", acceptEnc[0])) } } // 检查gRPC是否实际应用了压缩 if comp, ok := compressor.FromContext(ctx); ok { logger.Infow(ctx, "Response compressed", zap.String("compressor", comp.Name()), zap.String("method", info.FullMethod), ) } else { logger.Infow(ctx, "No response compression applied", zap.String("method", info.FullMethod)) } duration := time.Since(start) logger.Infow(ctx, "Request handled", zap.String("method", info.FullMethod), zap.Duration("duration", duration), zap.String("peer", p.Addr.String()), zap.Error(err), ) return resp, err } }
注意:compressor.FromContext(ctx)只有当gRPC确实对响应进行压缩时才会返回有效实例。如果客户端不支持压缩、响应体积过小不值得压缩,或者未匹配到启用的压缩算法,gRPC会跳过压缩,此时该方法返回ok=false。
3. 抓包直接验证
用Wireshark或tcpdump抓取gRPC请求的数据包,查看响应头中的grpc-message-encoding字段,如果值为你启用的压缩算法(如gzip),同时响应体为压缩后的二进制数据,就说明压缩已生效。
内容的提问来源于stack exchange,提问作者Aditya Nigam
相关产品推荐
相关产品推荐

