Kratos HTTP服务需显式创建并注入kratos.NewApp(),手动调用v1.RegisterXXXHTTPServer注册路由,且接口路径默认带/v1前缀;漏任一环节均导致404。

Kratos 启动 HTTP 服务不是调用一个 Run() 就完事的,它默认会同时启动 HTTP 和 gRPC 两个服务,但 HTTP 路由不会自动注册——漏掉注册步骤,curl http://localhost:8000/xxx 就只会返回 404。
确认 HTTP Server 已正确创建并注入 App
Kratos 的 HTTP 服务必须显式构造并传入 kratos.NewApp(),不能只靠 http.NewServer() 然后丢着不管。常见错误是只写了 server 构造代码,却没放进 kratos.NewApp(kratos.Server(...)) 的选项里。
-
kratos.NewApp()的kratos.Server()参数必须包含你构造的*http.Server实例,否则该服务根本不会被启动 - 检查
cmd/helloworld/main.go中是否调用了app, _ := kratos.New(...),且kratos.Server(httpSrv)在参数列表中 - 如果用的是
kratos run命令,它会自动加载configs/config.yaml并按配置初始化 server;但若手动运行go run ./cmd/helloworld,需确保配置文件路径正确(如加-conf configs/config.yaml)
HTTP 路由必须显式注册,不扫包、不自动发现
Kratos 不像 Gin 那样自动扫描 func 注册路由,所有 HTTP handler 都得在 internal/server/http.go 里手写注册逻辑,否则服务起来也收不到请求。
- 检查
internal/server/http.go是否调用了v1.RegisterGreeterHTTPServer()(或你自己的RegisterXXXHTTPServer()) - 确认
api/v1/greeter_http.pb.go文件存在——它由make api或protoc-gen-go-http生成;缺失则注册函数不存在,编译可能通过但运行时报undefined: v1.RegisterGreeterHTTPServer - 注意路径前缀:HTTP 接口默认带
/v1前缀(由http.proto中的option (google.api.http) = { ... }控制),curl http://localhost:8000/say/hello会 404,要访问http://localhost:8000/v1/say/hello
端口监听与日志验证:别只看 “started”,要看具体地址
服务打印 “HTTP server started” 不代表它真在监听你预期的地址。Kratos 默认用 [::]:8000(IPv6 any),但在某些 Linux 环境或 Docker 里可能因网络配置失败而静默降级或退出。
- 启动后立刻查日志,确认输出类似:
INFO ts=... caller=http/server.go:302 msg="[HTTP] server listening on: [::]:8000" - 用
lsof -i :8000或netstat -tuln | grep :8000验证进程是否真在监听该端口 - 如果想强制 IPv4,可在配置中设
http: { address: "0.0.0.0:8000" },避免[::]导致的兼容性问题 - 若日志没输出监听信息,大概率是
http.Server.Start()没被调用,或app.Run()被提前 return 了
最常被忽略的一点:Kratos 的 HTTP server 生命周期完全由 app.Run() 管理,不是启动后就一直跑着——如果你在 main() 里 app.Run() 后还写了其他阻塞逻辑,或者 panic 早于 app.Run(),服务压根不会进入监听状态。


















