Kratos本身不是网关框架,不提供路由转发、协议转换、全局限流等能力;可行方案只有独立部署fregata服务或基于Kratos开发BFF层,硬加HTTP路由规则仅得假网关。

Kratos 本身不解决网关路由转发问题——它压根不是网关框架。所谓“Kratos 网关”,实际只有两种可行路径:用独立的 fregata 服务,或自己基于 Kratos 写 BFF 层。硬在 Kratos 服务里加一堆 http.ServeMux 路由规则,只会得到一个假网关:无法协议转换、不能动态上游发现、也不支持全局限流。
kratos.New() 启动就 panic,但没报配置路径
这是最常卡住的第一步。panic 表面看是空指针或 nil dereference,根因其实是 conf.Load() 没前置调用——kratos.New() 内部会立刻执行它,而你还没注册任何 config.Provider。
- 必须在
main()第一行执行conf.Load(config.NewFile("configs/gateway.yaml")),不能等日志初始化或 flag 解析完再做 -
configs/gateway.yaml必须存在且可读;conf.Load()返回error时要显式检查并os.Exit(1),否则后续 panic 更难定位 - 别指望
$CONFIG_PATH自动替换:config.NewFile(os.Getenv("CONFIG_PATH"))需手动拼路径,Kratos 不解析变量语法
HTTP 路由 404,但 gRPC 能连上
说明 HTTP Server 进程活着,只是路由根本没挂到 mux 上。Kratos 的 HTTP 路由不自动扫描注册,全靠手动绑定。
- 确认
internal/server/http.go中创建了http.NewServer()实例,并传入了 handler(比如*gin.Engine或自定义http.ServeMux) - 确认
api/v1/gateway_http.pb.go已生成(即执行过make api),否则v1.RegisterGatewayHTTPServer()函数不存在 - 确认 proto 中
option (google.api.http)声明的路径带前缀,例如get: "/v1/route",不是get: "/route"——该前缀是代码生成时硬编码的 - 漏传
httpSrv到kratos.New(kratos.Server(httpSrv, grpcSrv)),等于没启用 HTTP 监听
fregata 启动后 HTTP → gRPC 转发失败
fregata 的核心能力(协议转换)完全依赖 proto 定义。它不是靠反射或约定,而是解析 .proto 文件生成反向代理逻辑。没 proto,就只能做透明 HTTP 转发,失去 Kratos 生态最大优势。
- proto 文件必须放在
api/子目录下,kratos proto server只扫描该路径 -
package名必须与目录结构严格一致,如api/greeter/v1/greeter.proto对应kratos.api.greeter.v1 - 必须显式
import "google/api/annotations.proto",缺了它,option (google.api.http)整行被 protoc 忽略 - 确保已安装
google.golang.org/api/annotations,否则protoc-gen-go-http插件无法工作
真正难的不是写转发逻辑,而是让上游服务能被发现、被健康探测、被按权重分发——这些能力 Kratos 不提供现成网关模块,必须自己集成服务发现(如 Consul)、实现 proxy.RoundTripper、填充 discovery.Instance.Weight 字段,否则 wrr 策略永远不生效。











