Kratos的gRPC配置关键在三处:proto的go_package需与模块路径和目录严格对齐;kratos.yaml中server.grpc配置须被cmd/main.go显式加载;避免重复Listen及端口冲突。

Kratos 的 gRPC 配置不是写一堆 YAML 就完事,关键在三处:proto 定义是否合规、生成代码路径是否匹配 internal 结构、kratos.yaml 里 server.grpc 配置是否被实际加载。
proto 文件必须带 go_package 且路径与项目结构对齐
很多新手跑不起来,第一关就卡在 protoc 生成失败或生成的代码 import 报错。根本原因是 go_package 值和你项目的 Go module 路径、目录层级不一致。
-
go_package必须是完整导入路径,比如你的模块是helloworld,proto 在api/helloworld/v1/greeter.proto,那就要写option go_package = "helloworld/api/helloworld/v1;v1"; - 生成 client 时用
kratos proto client api/helloworld/v1/greeter.proto,它会把代码放到api/下;server 代码用kratos proto server api/helloworld/v1/greeter.proto -t internal/service,强制落到internal/service/目录 - 如果
go_package写成"./v1"或漏掉分号后的包名(如只写"helloworld/api/helloworld/v1"),go build会提示cannot find package
kratos.yaml 中的 grpc.addr 不生效?检查 cmd 是否调用了配置
Kratos 不是自动读取 kratos.yaml 里的所有字段——server.grpc 这段配置,必须被 cmd/helloworld/main.go 显式传给 gRPC server 初始化逻辑,否则等于没写。
- 确认
cmd/helloworld/main.go中有类似srv := grpc.NewServer(conf.Server.GRPC)的调用,且conf.Server.GRPC是从配置文件解析出来的结构体 -
conf/conf.go里定义的ServerConfig必须嵌套GRPC *GRPCConfig字段,并用yaml:"grpc"tag 映射 - 如果手动改过
kratos.yaml但服务还是监听默认端口(比如 9000 没变),大概率是配置没反序列化进 struct,用fmt.Printf("%+v", conf.Server.GRPC)打印下看是否为 nil
启动时报 failed to listen: address already in use?先查 Listen 是否重复
Kratos 默认会在 internal/server/grpc.go 里调用 grpc.NewServer() 并绑定地址,但如果你手抖在 main.go 或别处又写了 net.Listen("tcp", "..."),就会冲突。
- 检查
internal/server/grpc.go的NewGRPCServer函数,它内部已调用grpc.NewServer和net.Listen,不要在外面再 listen - 确保没有同时启用 HTTP 和 gRPC server 却共用同一端口(HTTP 默认走 8000,gRPC 默认 9000,但有人会改成一样)
- Mac 上用
lsof -i :9000或 Linux 用ss -tulpn | grep :9000确认端口占用来源,避免残留进程干扰
真正容易被忽略的是:Kratos 的配置加载顺序和 struct tag 绑定非常严格,yaml 文件里多一个空格、少一个 -、字段名大小写错,都可能导致整个 grpc 段被忽略而不报错——它就安静地用默认值启动了。建议第一次配完,直接打印 conf.Server.GRPC.Addr 看输出,比反复猜强得多。


















