灰度发布到一半,调用新加的 QueryByTrace 方法,约三成请求报 rpc error: code = Unimplemented desc = unknown service order.OrderService,重试几次又能成功。第一次遇到会往复杂处想,其实漏掉的多是个小前提。

grpcurl -plaintext -d '{"traceId":"abc"}' \
  127.0.0.1:9090 order.OrderService/QueryByTrace

滚动升级期间新老实例同时在注册中心,客户端拿到老实例的地址就会调到不存在的方法。gRPC 的方法表在进程启动时固定,老实例不会因为 proto 更新而多出方法。这一点先确认清楚,后面就不用反复试。

碰到「gRPC 方法版本兼容」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。

改完隔一天再看一次,当场正常不代表能稳住。

具体做法是,新方法先发服务端 全量完成后再让客户端调用;客户端对 Unimplemented 做重试并剔除该实例 别当成业务失败;服务注册带上版本号 网关按版本路由;观察一个发布周期 确认 Unimplemented 计数归零。

改完照着核一遍,发布期间 Unimplemented 的计数不再上涨 新方法调用全部成功。

作者 9823189