kratos 启动 panic 多因 kratos.new() 传入 nil 的 server 或 registry,需检查 http/grpc.newserver()、consul.new() 是否成功;proto 未更新常因 go_package 不一致或 paths=source_relative 缺失;http 中间件需显式传递 context;consul 状态 critical 通常因健康检查路径未配置或网络不可达。

kratos.New() 初始化失败报 panic: runtime error: invalid memory address
Kratos 启动时直接 panic,大概率是 kratos.New() 传入了 nil 的 server.Server 或 registry.Registry,而框架没做防御性检查。这个错误不提示具体哪个参数为空,容易卡住。
- 检查
kratos.New()调用前是否漏掉了http.NewServer()、grpc.NewServer()或consul.New()等构造逻辑——它们返回值可能为 nil(比如配置错误或连接失败) - 不要在
main()里直接写kratos.New(kratos.WithServers(nil))这类硬编码;先确保每个 server 实例已成功创建并赋值 - Consul 注册中心未启动时,
consul.New()会返回 nil + error,但很多人只判 error 忽略了实例本身,导致传给kratos.New()的是 nil
proto 文件生成的 *.pb.go 和 *.grpc.pb.go 不更新
Kratos 强依赖 Protobuf 代码生成,改了 .proto 却没生效,90% 是因为生成命令没覆盖原文件,或 import 路径和 go_package 不一致。
- 确认
.proto顶部有正确的option go_package = "xxx/yyy;zzz";,其中zzz是 Go 中实际 import 的包名,必须和生成后文件的package zzz严格一致 - 生成命令要用
protoc --go_out=paths=source_relative:. --go-grpc_out=paths=source_relative:. xxx.proto,漏掉paths=source_relative会导致生成路径错乱 - 如果项目用了
kratos proto client或kratos proto server,它们内部调的是 protoc,但默认不清理旧文件——手动删掉旧*.pb.go再重跑更可靠
HTTP 中间件里拿不到 ctx.Value() 传入的值
Kratos 的 HTTP Server 默认用的是标准 net/http,中间件链中 ctx 是从 http.Request.Context() 拿的,不是 Kratos 自己的全局 context。你往 context.WithValue() 塞的东西,如果没显式传递进 request context,就丢了。
- 在中间件中想透传数据,必须用
req = req.WithContext(context.WithValue(req.Context(), key, val)),再调next.ServeHTTP(w, req) - 别依赖
transport.HTTPContext()返回的 context 去塞值——它只是个空 context,不关联 request 生命周期 - 如果用的是
transport.HTTPRequestContext()(注意名字差一个词),它才是包装过的、带 transport info 的 context,但依然要靠WithValue显式注入才能往下传
服务注册到 Consul 后状态一直是 critical
Kratos 默认开启健康检查(health check),但没配好检查路径或服务端没暴露 /health 接口,Consul 就一直标成 critical。
- 确认你的 HTTP Server 已注册了 health handler:
httpSrv.Handle("/health", http.HandlerFunc(healthHandler)),且healthHandler返回 200 - 检查
consul.New()时传的consul.WithHealthCheck()参数:如果启用了,必须保证check.HTTP指向的服务地址可被 Consul 访问(注意容器网络、host 配置) - 本地开发时 Consul 在 Docker 里,而服务跑在宿主机,
check.HTTP写http://localhost:8000/health是不通的——得换成http://host.docker.internal:8000/health(Mac/Win)或宿主机真实 IP(Linux)
register failed 或 health check timeout,比盯着 panic 更快定位。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











