kratos.New()启动panic的根本原因有三个:未在main()第一行调用conf.Load()注册配置源、未创建http/grpc.Server实例、未将实例传入kratos.New()的Server参数列表。

kratos.New() 启动就 panic,不是代码写错了,是基础初始化漏了三件事
conf.Load() 必须在 main() 第一行调用
kratos 内部启动时会立即尝试加载配置,但默认没注册任何 config.Provider。它不报“找不到 app.yaml”,而是直接 panic:no config provider registered——这个错误没路径、没上下文,纯靠经验定位。
必须在 main() 函数第一行就调用 conf.Load(),不能等日志初始化完、flag 解析完或 wire 构建完再做。
-
conf.Load()需显式传入至少一个 provider,例如config.NewFile("configs/app.yaml") - 别指望 kratos 自动解析环境变量:像
$CONFIG_PATH这种写法不会被展开,得自己拼进config.NewFile(os.Getenv("CONFIG_PATH")) - 如果
configs/app.yaml不存在,c.Load()会返回error,必须检查;否则后续 panic 更难追
kratos.New() 的 Server 参数不能为空
kratos.New() 不会帮你创建 server,只负责聚合和启动。漏传 http.Server 或 grpc.Server 实例,就会 panic 或服务监听失败。
- 确认是否调用了
http.NewServer()和/或grpc.NewServer(),且返回值非 nil(比如 consul 初始化失败时consul.New()可能返回(nil, err),只判err会漏掉) - 必须把 server 实例传进
kratos.Server(httpSrv, grpcSrv),漏传grpcSrv就等于没启 gRPC - gRPC 监听地址别写
localhost:9000:某些容器或 CI 环境下localhost解析失败,改用0.0.0.0:9000 - 如果项目压根不用 gRPC,就别调
service.Register()——HTTP 路由完全独立,不需要它也能跑 REST 接口
proto 编译必须带 protoc-gen-go-grpc 插件
生成的 *.pb.go 文件里没有 RegisterXXXServiceServer,说明你只装了 protoc-gen-go,缺的是 v2 版本的 protoc-gen-go-grpc。
-
protoc-gen-go(v1)只生成数据结构和 client stub;protoc-gen-go-grpc(v2)才生成 server 注册函数和 HTTP 映射逻辑 - 命令必须带
paths=source_relative:例如protoc --go-grpc_out=paths=source_relative:. device.proto,否则生成路径错乱,RegisterX找不到 - 建议两个插件一起用:
--go_out+--go-grpc_out+--go-http_out(后者用于 HTTP 映射)
service.Register() 报 rpc error: code = Unavailable 是因为 grpc.Server 没真正运行
service.Register() 不是向远程注册,而是向本进程内已运行的 grpc.Server 实例注册。失败只说明一件事:server 没启,或者没传给 kratos.New()。
- 检查日志是否有类似
start grpc server at [::]:9000的输出;没有就代表没起来 - 确认
grpc.Server实例是否被正确注入到 wire 的 provider set,并最终传入newApp()函数 - 注意:wire 构建后生成的
wire_gen.go是只读文件,别手动改;每次改依赖都要重新执行wire
conf.Load() 漏位置、Server 漏传参、proto 插件漏版本,这三个地方卡住,整个服务连启动都做不到。


















