必须匹配protoc与go插件版本,如protoc 3.21.12需配protoc-gen-go@v1.33.0和protoc-gen-go-grpc@v1.4.0,否则生成代码失败;go_package须写全路径,grpc.dial应全局复用并调用close,proto字段需显式加json_name,流式rpc须主动判错。

protoc 和 Go 插件必须匹配版本,否则生成代码失败
常见错误是 protoc --version 输出 libprotoc 3.21.12,但 protoc-gen-go 却用的是 v1.32+,导致生成的 .pb.go 文件里出现未定义的 func (*XXX) XXXSize 或编译报错 undefined: proto.RegisterType。
- 验证方式:运行
protoc-gen-go --version和protoc-gen-go-grpc --version,确保它们与protoc主版本号一致(如都是 3.21.x) - 推荐安装方式(避免版本漂移):
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.33.0+go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.4.0,再对应下载protoc-3.21.x二进制 -
go_package必须写全路径(如option go_package = "github.com/myorg/myapp/pb";),否则生成的 import 路径错乱,Go build 找不到包
客户端连接不能每次调用都 grpc.Dial
新手常把 grpc.Dial 放在函数内部,一请求一连,结果压测时 CPU 狂飙、socket 耗尽,日志满屏 context deadline exceeded 或 connection refused——其实服务端完全正常,是客户端自己连不上了。
- 正确做法:全局复用一个
*grpc.ClientConn,它线程安全,可并发调用多个rpc方法 - 别用
WithBlock(),它会让Dial同步阻塞直到连接 ready,线上可能卡死;改用异步健康检查:conn.GetState() == connectivity.Ready - 务必在进程退出前调用
conn.Close(),否则 goroutine 和底层 TCP 连接不会释放,内存和 fd 持续泄漏
proto 字段名和 Go JSON 标签不一致,导致 grpc-gateway 返回空字段
用 grpc-gateway 暴露 HTTP 接口时,明明 UserResponse 有数据,curl 却返回 {"user_id": null},根本原因是 proto 字段命名没对齐 Go 的 JSON 序列化规则。
- proto 字段必须用
snake_case,且显式加[json_name = "user_id"],例如:string user_id = 1 [json_name = "user_id"]; - 不要依赖 Go 结构体的
json:"user_id"tag ——grpc-gateway直接读 proto 的json_name,不走 Go struct tag -
repeated string tags = 5;对应 Go 切片,但nil和[]string{}序列化行为不同:nil不出现在 wire 上,[]string{}会序列化为空数组;建议初始化为[]string{}
流式 RPC 必须主动判错,否则 goroutine 永远卡住
服务端写 stream.Send() 循环推送数据,客户端一断开,服务端就 hang 在 Send 上,CPU 不高但 goroutine 积压,最后 OOM —— 因为 gRPC 不会自动中断发送,你得自己检查。
- 每个
stream.Send(msg)后必须判断错误:if err != nil { return err } - 循环中持续检查
stream.Context().Err() != nil,一旦为真立即return - 别用
context.Background()替代stream.Context(),前者无取消信号,后者随客户端断开自动 cancel - 需要背压控制时,可用
stream.SetHeader()传起始 offset 或 batch size,或改用双向流让客户端确认就绪
SayHello,而是当 QPS 上千、流持续数分钟、proto 字段增删改后,连接是否泄漏、流是否 hang 死、字段是否错位。这些点不在教程里,但在上线后每晚三点准时出现。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











