实测 gRPC 的名字解析:passthrough 与 dns 的差别、默认端口、一个域名多条 A 记录、DNS TXT 里的服务配置默认生效、TTL 被无视、重新解析的时机受 30 秒最小间隔限制、解析失败的表现。
实测 gRPC 长连接的负载不均:按连接分配的四层均衡器在新增后端后,已有的连接不会迁移,新后端一个请求都没有;客户端请求量不同会让后端负载悬殊;客户端自己 round_robin 与服务端 MaxConnectionAge 各自怎么解决。
实测 gRPC 拦截器:链式拦截器的洋葱顺序、单个拦截器总在最外层、能改 ctx/metadata/返回值、能短路、流拦截器只调用一次要包装才能数消息、panic 不 recover 会让进程退出、空拦截器的开销。
实测 gRPC 服务配置里的重试策略:重试几次、等多久(退避带 ±20% 随机)、哪些错误码、最多 5 次的客户端上限、响应头发出后不重试、请求超过 256 KiB 不重试、服务端 pushback,以及 grpc-go 没有实现 hedging。
实测请求积压的内存:内存队列每个请求约 1 KiB(50,000 个增加 54.9 MiB,带 1 KB meta 变 120.1 MiB),启用 JOBDIR 后 RSS 只涨 0.2 MiB、start() 慢约 20%、落盘 11.1 MiB(每个请求约 234 字节)。
实测 gRPC 的 retryThrottling 令牌桶:故障时重试被限制、服务端负载放大从 3 倍压到 1 倍;恢复要连续成功 60 多次;部分故障下节流会把最终失败率从 0.6% 拉到 20.0%;配置非法时 NewClient 报错。
实测 Request.priority:必须是整数(浮点、字符串、None 构造时 TypeError,负数和 10**30 都行);出队严格按优先级但并发高时到达顺序会乱(并发 60 时 133 个逆序对);优先级只比较出队那一刻已排队的请求,链式产生的高优先级请求不会饿死排队的低优先级请求。
实测 grpc.health.v1:Check 对没登记的服务返回 NotFound、NOT_SERVING 是成功的响应;Watch 对没登记的服务先给 SERVICE_UNKNOWN、快速变化会被合并;Shutdown 之后设置被忽略;客户端要配置 healthCheckConfig 才会摘掉不健康的后端。
实测 gRPC 服务端反射:Register 同时注册 v1 和 v1alpha 且列出自己;客户端通过 FileContainingSymbol 拿到 .proto 的描述符并列出方法和字段;只靠描述符用 dynamicpb 动态调用;找不到符号是响应里的错误而不是 RPC 失败。
实测 gRPC 的错误详情:details 走 trailers 里的 grpc-status-details-bin;一个错误可以带 ErrorInfo、BadRequest、RetryInfo 等多种标准类型;details 太大(20 MiB)连接会出错;不认识的类型变成 error 项;A 调 B 时 details 如何透传。
实测 gRPC 的 gzip 压缩:可压缩数据线上字节只剩 0.5%~9.6%,随机数据不变;压缩标志位和 grpc-encoding;服务端 SetSendCompressor;回环上 gzip 的 CPU 代价(类 JSON 文本慢 5.7 倍);级别 9 几乎不更小;服务端不认识的算法返回 Unimplemented。
实测 gRPC 的消息大小限制:默认接收上限 4194304 字节比的是序列化后的整条消息;服务端、客户端各自的报错;拒绝 64 MiB 请求前线上只传了约 64 KiB;限制按单条消息而不是流;压缩后不算、解压后才算;怎么调大。