grpc 报错 rpc: the client connection is closing

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值