Go-Micro v3+默认使用HTTP传输而非gRPC,因架构解耦后transport、codec等模块独立,默认transport为HTTP、codec为JSON,即使替换protobuf codec仍走HTTP POST;要启用gRPC必须改用grpc.NewService()初始化并显式配置地址,同时客户端需匹配grpc.Dial()或grpc.NewClient(),否则协议不匹配导致调用失败。

Go-Micro 3.x 及以后版本已移除对 gRPC 的原生支持,micro.NewService() 默认使用 HTTP 协议,直接启用 gRPC 需手动集成 grpc-go 并替换默认传输层和客户端 —— 这不是配置开关能解决的,而是架构级替换。
为什么 micro.NewService() 启动后不走 gRPC?
Go-Micro v3+(包括 v4)将传输(transport)、编码(codec)、客户端/服务端抽象完全解耦,默认 transport 是 HTTP,codec 是 JSON。即使你用 micro.WithCodec() 换成 protobuf,底层仍是 HTTP POST 请求,不是 gRPC 的 HTTP/2 + Protocol Buffers 二进制流。
-
micro.NewService()不会自动启动 gRPC Server,也不会监听0.0.0.0:50051这类典型 gRPC 端口 - 调用
service.Client().Call()发出的是 HTTP JSON 请求,不是 gRPC Unary RPC - 如果你看到
rpc error: code = Unimplemented desc = Method not found,大概率是因为客户端在发 HTTP 请求,而服务端实际跑的是 gRPC Server(或反过来)
如何让 Go-Micro 服务真正运行在 gRPC 上?
必须放弃 micro.Service 的默认 transport,改用 grpc.NewService()(来自 github.com/micro/go-micro/v4/server/grpc),并显式构造 gRPC Server 实例。这不是“加个选项”,而是换掉服务初始化方式。
- 导入正确包:
import "github.com/micro/go-micro/v4/server/grpc"(注意 v4 路径,v3 路径不同) - 不用
micro.NewService(),改用grpc.NewService()初始化服务实例 - 注册 Handler 时,需实现
proto.RegisterXxxHandlerServer接口,而非micro.RegisterHandler - gRPC Server 默认监听
localhost:0(随机端口),需用server.Address("0.0.0.0:50051")显式指定
示例关键片段:
srv := grpc.NewService(
micro.Name("go.micro.srv.greeter"),
server.Address("0.0.0.0:50051"),
)
// 注意:这里不是 micro.RegisterHandler,而是直接传入 proto 生成的 server 实例
pb.RegisterGreeterHandlerServer(srv.Server(), &handler{})
if err := srv.Run(); err != nil {
log.Fatal(err)
}
客户端调用 gRPC 接口时为何报 connection refused 或 unavailable?
Go-Micro 客户端默认不兼容裸 gRPC Server;如果你服务端用了 grpc.NewService(),客户端就不能再用 service.Client().Call(),否则它仍会尝试 HTTP 连接。
- 要调用 gRPC Server,客户端必须用
grpc.Dial()直连,而不是通过 Go-Micro 的Client抽象 - 若坚持用 Go-Micro Client,需配套使用
grpc.NewClient()替换默认 client:micro.NewService(micro.Client(grpc.NewClient())) - 但即使如此,仍要求服务端也用
grpc.NewService(),且双方 proto service name、method name、message 结构严格一致 - 常见坑:proto 文件里
package和service名与 Go-Micro 的micro.Name()不一致,导致 registry 中注册失败或路由错乱
真正用 Go-Micro 写 gRPC 微服务,核心是接受它已不是“开箱即用”的 gRPC 封装,而是需要你主动选择 transport 层并承担对应适配成本。很多团队最终绕过 Go-Micro 的 server/client 抽象,直接用 grpc-go + etcd 做服务发现,反而更可控。


















