kratos服务调用失败报unavailable或deadline exceeded,根本原因是grpc连接未建立或服务未注册:需确认grpc.server已创建并传入kratos.new()、监听地址用0.0.0.0而非localhost、端口处于listen状态;service.register()失败因proto未用protoc-gen-go-grpc+go-http插件生成注册函数,或未在grpc.go中调用pb.registerxxxserver;客户端须配insecure.newcredentials()(开发)或tls(生产);http 404因未调用v1.registerxxxhttpserver且api文件未生成;kratos.new() panic因conf.load()未在main()首行调用且未传config.provider。

Kratos框架服务调用失败时,客户端收不到响应、报错code = Unavailable或context deadline exceeded,不是网络抖动或业务写错了,而是底层gRPC连接根本没建起来或服务端压根没注册成功。
确认gRPC Server是否真正启动并监听
第一步:检查internal/server/grpc.go中是否创建了grpc.Server实例,且传入kratos.New()的Server参数列表中。漏传grpcSrv就等于没启gRPC服务,所有调用必然失败。
第二步:验证监听地址是否写成localhost:9000。某些容器或CI环境无法解析localhost,必须改用【0.0.0.0:9000】,否则服务虽启动但对外不可达。
第三步:运行服务后,执行netstat -tuln | grep :9000,确认端口处于LISTEN状态。若无输出,说明grpc.Server未绑定端口,常见原因是NewServer()返回nil(如consul初始化失败却只判error未判实例)。
检查服务是否完成注册
service.Register()报rpc error: code = Unavailable,本质是向一个空的grpc.Server注册——它还没start,或者你根本没创建它。
方法一:确认proto文件已正确生成服务注册函数。必须用protoc-gen-go-grpc(v2版)+ protoc-gen-go-http两个插件一起生成,且命令带paths=source_relative。缺任一插件或参数,pb.RegisterXXXServiceServer函数就不存在,编译可能通过,运行时直接panic。
方法二:检查internal/server/grpc.go中是否调用了pb.RegisterGreeterServer(grpcSrv, &service.GreeterService{})。kratos proto server生成的只是空壳接口,不手动注册,服务永远不会被gRPC Server感知。
排查客户端连接配置问题
客户端调用时出现context deadline exceeded或panic: "credentials: no credentials specified",大概率是传输凭据缺失。
本地开发必须显式配置grpc.WithTransportCredentials(insecure.NewCredentials()),否则gRPC拒绝建立明文连接。生产环境则需配credentials.NewTLS(tlsConfig),且服务端ServerOption中的TLSConfig必须与之匹配,否则握手失败。
如果启用了etcd服务发现,还要确认是否传入了grpc.WithResolvers和grpc.WithAuthority。漏掉resolvers会导致客户端根本找不到服务实例地址,调用永远超时。
验证HTTP网关是否生效
调用HTTP接口返回404,不是路由写错了,而是HTTP Server没注册对应服务。
检查internal/server/http.go中是否调用了v1.RegisterGreeterHTTPServer(httpSrv, &service.GreeterService{})。这个注册动作和gRPC注册完全独立,漏掉就等于没暴露HTTP接口。
确认api/v1/greeter_http.pb.go已生成(即执行过make api)。该文件不存在,RegisterGreeterHTTPServer函数就不存在,代码编译会直接报错。
注意路径前缀默认是/v1,比如curl http://localhost:8000/v1/say/hello。这个前缀由http.proto里的option (google.api.http) = { get: "/say/hello" };控制,不是硬编码在代码里。
定位配置加载失败根源
kratos.New()一启动就panic: no config provider registered,不是配置文件路径错,是conf.Load()根本没被调用,或调用时机太晚。
【conf.Load()必须放在main()函数第一行】,不能等flag.Parse()或log.Init()之后再调。它内部会主动触发配置加载,但默认没注册任何Provider。
conf.Load()需显式传入至少一个config.Provider,例如config.NewFile("configs/app.yaml")。别依赖os.Getenv("CONFIG_PATH")自动替换——kratos不解析$符号,得自己拼进去。
如果configs/app.yaml文件不存在,c.Load()会返回error,必须检查。忽略这个error,后续所有基于配置的操作都会panic,且错误堆栈更难追踪。











