是跨 goroutines 的 gRPC 客户端/存根使用

我正在试验 Protobuf 和 gRPC,并且正在学习 Go 基础教程:https ://www.grpc.io/docs/languages/go/basics/


从我在有关 ClientConn 的文档中看到的内容来看,同时使用相同的ClientConn似乎是安全的。但是我对创建的存根/客户端一无所知......


假设我通过 HTTP POST 请求接收数据,我想通过 gRPC 作为 protobuf 转发该数据,然后响应 HTTP 请求。我应该在每次处理 HTTP 请求时都创建一个客户端/存根,还是可以在设置 HTTP 服务器时创建客户端/存根并在设置 HTTP 处理程序时传入客户端/存根?


示例:我认为这没问题


var opts []grpc.DialOption

conn, err := grpc.Dial("127.0.0.1:1234", opts...)

if err != nil {

    log.Panic(err)

}

defer conn.Close()

grpcService := service.Service{GRPC: conn}

http.HandleFunc("/", util.ValidateRequest(grpcService.HandleRoot))


// listen to port

http.ListenAndServe(fmt.Sprintf("%s:%d", viper.GetString("server.address"), viper.GetInt32("server.port")), nil)

但是这个呢


var opts []grpc.DialOption

conn, err := grpc.Dial("127.0.0.1:1234", opts...)

if err != nil {

    log.Panic(err)

}

defer conn.Close()

client := pb.NewEventShipperClient(conn)

grpcService := service.Service{GRPC: conn, Client: client}

http.HandleFunc("/", util.ValidateRequest(grpcService.HandleRoot))


// listen to port

http.ListenAndServe(fmt.Sprintf("%s:%d", viper.GetString("server.address"), viper.GetInt32("server.port")), nil)


catspeake
浏览 82回答 1
1回答

慕尼黑的夜晚无繁华

生成代码参考中涵盖了线程安全(“同时运行它是否安全”):线程安全:请注意,客户端 RPC 调用和服务器端 RPC 处理程序是线程安全的,旨在并发 goroutines 上运行。但还要注意,对于单个流,传入和传出数据是双向的但串行的;因此,例如,单个流不支持并发读取或并发写入(但读取与写入是安全并发的)。所以,是的,可以同时调用struct返回的方法。pb.NewEventShipperClient(conn)您也可以通过查看pb.NewEventShipperClient. 目前(我想这可能会改变)唯一的成员变量将是一个接口(cc grpc.ClientConnInterface- 实现*ClientConn),每个方法都使用到InvokegRPC 调用的连接。但是请注意,您在实施时需要小心,service.Service以确保它也是线程安全的,并注意有关流的警告。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go