gRPC 单条消息默认最大多少?超了是什么错?在哪一端检查?压缩能不能绕过?这篇用二分查出精确的临界点,并看了拒绝之前线上传了多少数据。
最大能通过的 payload 4194299 字节 → 序列化后的消息 4194304 字节;再多 1 字节的 payload 4194300 → 消息 4194305 字节(4 MiB = 4194304) 再多一字节时的错误:code=ResourceExhausted message="grpc: received message larger than max (4194305 vs. 4194304)"
服务端和客户端接收的默认上限都是 4 MiB;发送的默认上限是 MaxInt32(基本不限)。比较的是序列化后的整条消息。
服务端收 5 MiB 的请求:code=ResourceExhausted message="grpc: received message larger than max (5242885 vs. 4194304)" 客户端收 5 MiB 的响应:code=ResourceExhausted message="grpc: received message larger than max (5242885 vs. 4194304)" 客户端 MaxCallSendMsgSize(1 MiB) 发 2 MiB:code=ResourceExhausted message="trying to send message larger than max (2097157 vs. 1048576)";线上客户端发出的 HEADERS 1 个
超限一律是 ResourceExhausted。服务端拒绝请求、客户端拒绝响应、客户端本地拒绝发送,消息文字不同。
64 MiB 的请求:code=ResourceExhausted message="grpc: received message larger than max (67108869 vs. 4194304)";耗时 14.7 ms;客户端→服务端的线上字节 65670(0.06 MiB,占消息的 0.1%)
接收方读到 5 字节的消息前缀就知道长度,超限立刻结束这个流,不会等整条消息传完。
10 条 3 MiB:Send 错误 <nil>;服务端数到 10 条;最终 成功(总共 30 MiB) 先 1 MiB 再 5 MiB:code=ResourceExhausted message="grpc: received message larger than max (5242885 vs. 4194304)"
限制是单条消息的,流里可以发很多条,总量不受限制。
默认上限 4 MiB :code=ResourceExhausted message="grpc: received message after decompression larger than max 4194304";线上客户端→服务端 205887 字节(201.1 KiB) MaxRecvMsgSize(128 MiB) :成功;线上客户端→服务端 205917 字节(201.1 KiB)
压缩后的大小不算,解压后的大小才算,压缩不能绕过限制。
发 32 MiB 请求:成功,耗时 29.4 ms;收 32 MiB 响应:成功,耗时 21.8 ms
服务端 MaxRecvMsgSize/MaxSendMsgSize,客户端 MaxCallRecvMsgSize/MaxCallSendMsgSize,要两头都设。内存占用随之上升。