grpc 报错 rpc: the client connection is closing
第一次写golang微服务,也是第一次接触gprc,底层原理还不太了解,盲猜跟openFeign差不多生成代理类,但grpc好像专门开放了端口,用protobuf协议传输
项目用kratos框架,在服务A走grpc调用服务B后报错
code = Canceled desc = grpc: the client connection is closing
看报错原因是客户端连接关闭了,注册中心使用的nacos,服务发现完全按照kratos官方提供的代码实例,data层服务注册、服务发现代码如下:
func NewNacosServer(rg *conf.Registry) registry.Registrar {
sc := []constant.ServerConfig{
*constant.NewServerConfig(rg.Nacos.Address, rg.Nacos.Port),
}
client, err2 := clients.NewNamingClient(vo.NacosClientParam{ServerConfigs: sc})
if err2 != nil {
panic(err2)
}
r := nacos.New(client)
return r
}
func NewDiscovery(conf *conf.Registry) registry.Discovery {
sc := []constant.ServerConfig{
*constant.NewServerConfig(conf.Nacos.Address, conf.Nacos.Port),
}
cc := constant.ClientConfig{
NamespaceId: "public",
}
client, err := clients.NewNamingClient(
vo.NacosClientParam{
ClientConfig: &cc,
ServerConfigs: sc,
},
)
if err != nil {
panic(err)
}
return nacos.New(client)
}
func NewSocialClient(discovery registry.Discovery) v1.SocialClient {
conn, err := grpc.DialInsecure(
context.Background(),
grpc.WithEndpoint("discovery:///social.grpc"),
grpc.WithDiscovery(discovery),
grpc.WithMiddleware(
recovery.Recovery(),
),
)
if err != nil {
panic(err)
}
defer conn.Close()
client := v1.NewSocialClient(conn)
return client
}
原因在于:
官方文档中的实例,main function中使用了defer()关闭连接,在defer归属的函数即将返回时,将延迟处理的语句按defer定义的逆序进行执行。 由于创建grpc客户端最终归属wireApp(),(依赖倒置实现解耦),在function main()中已经返回,就会执行NewSocialClient中的defer()将连接关闭,导致调用失败
关于defer、panic、recover
解决方法: 将NewSocialClient 中的defer conn.Close() 删除,即可解决
可能真正开发中有最佳实践,这个是我个人的项目,参考stackoverflow
|