gRPC 支持按消息压缩吗?怎么协商?压缩多少、花多少 CPU?这篇用本机回环测了 gzip 的体积变化和耗时变化,并看了线上的压缩标志位。
重复的 JSON 片段 客户端→服务端 不压缩 102672 字节 / gzip 510 字节(0.5%);服务端→客户端 不压缩 102677 / gzip 515 字节(0.5%);gzip 时请求的压缩标志位 1、grpc-encoding=gzip;响应的压缩标志位 1、grpc-encoding=gzip 随机字节 客户端→服务端 不压缩 102638 字节 / gzip 102593 字节(100.0%);服务端→客户端 不压缩 102643 / gzip 102598 字节(100.0%);gzip 时请求的压缩标志位 1、grpc-encoding=gzip;响应的压缩标志位 1、grpc-encoding=gzip 类 JSON 文本 客户端→服务端 不压缩 102562 字节 / gzip 9874 字节(9.6%);服务端→客户端 不压缩 102567 / gzip 9879 字节(9.6%);gzip 时请求的压缩标志位 1、grpc-encoding=gzip;响应的压缩标志位 1、grpc-encoding=gzip
客户端每个请求带 grpc-accept-encoding 声明能解的算法;用 UseCompressor 压缩请求时带 grpc-encoding,每条消息的 5 字节前缀里压缩标志位为 1。服务端默认用请求相同的算法回复,也可以在 handler 里用 SetSendCompressor 选一个客户端声明过的算法。
客户端 gzip,服务端不设置 请求标志位 1、响应标志位 1;请求头 grpc-accept-encoding=gzip;响应头 grpc-encoding=gzip;请求字节 628、响应字节 573;SetSendCompressor 返回 <nil> 客户端不压缩,服务端 SetSendCompressor(gzip) 请求标志位 0、响应标志位 1;请求头 grpc-accept-encoding=gzip;响应头 grpc-encoding=gzip;请求字节 102562、响应字节 610;SetSendCompressor 返回 <nil>
重复多的数据压到几十分之一,已经压缩的数据(随机字节)压不动,还要花 CPU。
重复的 JSON 片段 不压缩 1.9 ms;gzip 3.5 ms(1.8 倍) 类 JSON 文本 不压缩 1.6 ms;gzip 8.9 ms(5.7 倍) 随机字节 不压缩 1.5 ms;gzip 2.8 ms(1.9 倍)
在带宽几乎无限的回环上,压缩只增加耗时;在带宽受限的网络上才可能划算,需要在真实网络上测。
级别 1:请求 124969 字节(原始 1048576);往返 8.9 ms 级别 -1:请求 95455 字节(原始 1048576);往返 9.5 ms 级别 9:请求 95449 字节(原始 1048576);往返 31.7 ms
gzip.SetLevel 改的是全局设置。最高级别耗时数倍,体积几乎没有变化。
服务端不认识 fake:code=Unimplemented message="grpc: Decompressor is not installed for grpc-encoding \"fake\"";响应头里 grpc-accept-encoding=无 同一个连接上之后不压缩的调用:err=<nil>
服务端不认识就返回 Unimplemented,客户端不会自动退回到不压缩。