必须分别配置http和grpc两套server实例并使用不同端口,否则会因地址冲突启动失败;需确保cmd/main.go中调用两者构造函数、server.toml中配置独立addr、http.go和grpc.go中显式传入address选项,并通过日志和命令验证双端口监听成功。

要在Kratos服务中同时启用HTTP和gRPC两个独立端口,必须分别配置两套Server实例,且不能共用同一监听地址,否则启动时会报“address already in use”错误。
确认项目已生成双协议骨架
执行 kratos new helloworld 创建的默认项目已内置 HTTP + gRPC 双服务模板,目录结构中应存在 internal/server/http/ 和 internal/server/grpc/ 两个子包。若为手动迁移旧项目,需确保 cmd/main.go 中调用了 http.New() 和 grpc.New() 两处服务构造函数。
这一步不可跳过——【缺少任一 server 构造函数调用,对应协议服务将完全不启动】。
修改 configs/server.toml 配置双端口
打开 configs/server.toml 文件,在 [server] 段落下添加两个独立配置块:
[server.http]addr = "0.0.0.0:8000"timeout = "1s"[server.grpc]addr = "0.0.0.0:9000"timeout = "1s"
注意:两个 addr 的端口号必须不同,且不能与其他进程冲突;若写成相同端口(如都设为 :9000),gRPC Server 会因端口被 HTTP Server 占用而静默失败,日志中仅显示 “failed to listen” 且无进一步错误提示。
在 internal/server/http.go 中注入 HTTP Server 实例
打开 internal/server/http.go,确认 NewHTTPServer 函数返回的是 *http.Server 类型,并已传入 c.HTTP.Addr 和 router。
检查是否调用了 http.New() 工厂函数,且参数中包含 http.Address(c.HTTP.Addr) —— 这是绑定端口的关键,漏掉会导致服务监听在默认 :8000 而非配置文件指定值。
在 internal/server/grpc.go 中注入 gRPC Server 实例
打开 internal/server/grpc.go,确认 NewGRPCServer 函数返回的是 *grpc.Server 类型,并已传入 c.GRPC.Addr。
关键点在于:必须显式传入 grpc.Address(c.GRPC.Addr) 选项,否则即使配置文件写了 addr = ":9000",服务仍会监听在 :9000 的默认值上,但该行为不可靠,某些 Kratos v2.10+ 版本会直接 panic。
这一步操作起来很简单,直接把 grpc.Address(c.GRPC.Addr) 加到 grpc.New() 的参数列表末尾即可。
启动服务并验证双端口生效
第一步:执行 kratos run 启动服务;
第二步:观察控制台输出,应同时看到两行日志:
INFO server/http.go:45 [http] start http server at [::]:8000
INFO server/grpc.go:52 [grpc] start grpc server at [::]:9000
第三步:终端执行 netstat -an | findstr :8000(Windows)或 lsof -i :8000(macOS/Linux),确认 8000 和 9000 端口均处于 LISTEN 状态;
第四步:用 curl 测试 HTTP 接口:curl http://localhost:8000/health,返回 {"status":"ok"};
第五步:用 grpcurl 测试 gRPC 接口:grpcurl -plaintext localhost:9000 list,应列出已注册的服务名(如 helloworld.Greeter)。











