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()将连接关闭,导致调用失败

解决方法: 将NewSocialClient 中的defer conn.Close()删除,即可解决

可能真正开发中有最佳实践,这个是我个人的项目,参考stackoverflow

经验分享 程序员 微信小程序 职场和发展