Bonnes pratiques d'utilisation de gRPC pour mettre en œuvre la transmission simultanée de données dans Golang
Introduction :
Avec le développement du cloud computing et de la technologie du big data, la demande de transmission de données devient de plus en plus urgente. En tant que framework d'appel de procédure à distance hautes performances open source de Google, gRPC est devenu le premier choix de nombreux développeurs en raison de son efficacité, de sa flexibilité et de ses fonctionnalités multilingues. Cet article présentera les meilleures pratiques d'utilisation de gRPC pour réaliser une transmission simultanée de données dans Golang, y compris la construction de la structure du projet, l'utilisation de pools de connexions et la gestion des erreurs, etc.
1. Construire la structure du projet
Avant de commencer à utiliser gRPC, nous devons construire une structure de projet appropriée pour rendre l'organisation et la gestion du programme plus claires.
myproject ├── api │ └── myservice.proto │ ├── client │ ├── client.go │ └── main.go │ └── server ├── server.go ├── handler.go └── main.go
Parmi eux, le répertoire api est utilisé pour stocker la définition de l'interface du service gRPC, le répertoire client stocke le code et la fonction principale liés au client, et le répertoire serveur stocke code lié au serveur et fonction principale.
syntax = "proto3"; package myproject; service MyService { rpc GetData (GetDataRequest) returns (GetDataResponse) {} } message GetDataRequest { string id = 1; } message GetDataResponse { string data = 1; }
Un service nommé MyService est défini ici, comprenant une méthode RPC nommée GetData, qui reçoit un paramètre GetDataRequest et renvoie un paramètre GetDataResponse.
protoc --proto_path=./api --go_out=plugins=grpc:./api ./api/myservice.proto
Cela générera un fichier nommé myservice.pb.go dans le répertoire api, qui contient le service gRPC et Définition du message et autres codes associés.
2. Créez le client
Ensuite, nous commencerons à écrire le code client pour envoyer des requêtes simultanées au serveur et recevoir les données renvoyées.
package main import ( "context" "log" "sync" "time" "google.golang.org/grpc" pb "myproject/api" // 导入生成的代码 )
grpc.Dial
. L'exemple de code est le suivant : grpc.Dial
函数来创建连接。示例代码如下:func main() { // 创建连接并指定服务端地址和端口 conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err != nil { log.Fatalf("failed to connect: %v", err) } defer conn.Close() // 创建客户端 client := pb.NewMyServiceClient(conn) // 发送并发请求 var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func(id int) { defer wg.Done() // 创建上下文和请求 ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() req := &pb.GetDataRequest{ Id: strconv.Itoa(id), } // 调用服务端方法 resp, err := client.GetData(ctx, req) if err != nil { log.Printf("failed to get data: %v", err) return } // 输出结果 log.Printf("data: %s", resp.Data) }(i) } // 等待所有请求完成 wg.Wait() }
在上述代码中,我们首先使用grpc.Dial
函数创建与服务端的连接。这里采用了不安全的连接模式(Insecure),用于简化示例。实际应用中,建议采用安全的连接模式(Secure)。
然后,我们创建了一个MyServiceClient实例,用于调用服务端的方法。
接下来,我们使用sync.WaitGroup来协调并发请求。在循环中,我们创建了一个匿名函数,用于发起并发请求。在每个并发执行的请求中,我们创建了一个上下文和请求对象,然后调用服务端的方法GetData
。
最后,我们使用wg.Wait
来等待所有的并发请求完成。
三、创建服务端
接下来我们将开始编写服务端的代码,用于接收客户端的请求并返回处理后的数据。
package main import ( "log" "net" "google.golang.org/grpc" pb "myproject/api" // 导入生成的代码 )
package main import ( "context" ) // 定义服务 type MyServiceServer struct{} // 实现方法 func (s *MyServiceServer) GetData(ctx context.Context, req *pb.GetDataRequest) (*pb.GetDataResponse, error) { // 处理请求 data := "Hello, " + req.Id // 构造响应 resp := &pb.GetDataResponse{ Data: data, } return resp, nil }
这里我们实现了MyServiceServer结构体,并实现了GetData方法。在该方法中,我们首先处理请求,然后构造响应并返回。
grpc.NewServer
函数来创建服务。示例代码如下:func main() { // 监听TCP端口 lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } // 创建gRPC服务 s := grpc.NewServer() // 注册服务 pb.RegisterMyServiceServer(s, &MyServiceServer{}) // 启动服务 if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }
在上述代码中,我们首先使用net.Listen
函数创建一个TCP监听器,指定监听端口为50051。
然后,我们使用grpc.NewServer
函数创建一个gRPC服务,并使用pb.RegisterMyServiceServer
方法将我们实现的服务注册到该服务中。
最后,我们使用s.Serve(lis)
package main // main函数入口 func main() { // 注册服务 pb.RegisterMyServiceServer(s, &MyServiceServer{}) // 启动服务 if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }
Dans le code ci-dessus, nous utilisons d'abord la fonction grpc.Dial
pour créer une connexion avec le serveur. Le mode de connexion non sécurisée (Insecure) est utilisé ici pour simplifier l'exemple. Dans les applications pratiques, il est recommandé d'utiliser le mode de connexion sécurisée (Secure).
GetData
. Enfin, nous utilisons wg.Wait
pour attendre que toutes les requêtes simultanées se terminent. 3. Créez le serveur Ensuite, nous commencerons à écrire le code du serveur pour recevoir la demande du client et renvoyer les données traitées.
Importer les dépendancesDans server/main.go, nous devons d'abord importer les dépendances associées, y compris gRPC, log et net, etc. :
package main // main函数入口 func main() { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() req := &pb.GetDataRequest{ Id: "1", } resp, err := client.GetData(ctx, req) if err != nil { log.Fatalf("failed to get data: %v", err) } log.Printf("data: %s", resp.Data) }
go run server/main.go go run client/main.go
grpc.NewServer
. L'exemple de code est le suivant : 🎜🎜2021/01/01 15:00:00 data: Hello, 1
net.Listen
pour créer un écouteur TCP et spécifier le port d'écoute comme 50051. 🎜🎜Ensuite, nous utilisons la fonction grpc.NewServer
pour créer un service gRPC, et utilisons la méthode pb.RegisterMyServiceServer
pour enregistrer le service que nous avons implémenté dans le service. 🎜🎜Enfin, nous utilisons la méthode s.Serve(lis)
pour démarrer le service et écouter le port spécifié. 🎜🎜4. Démonstration d'un exemple de code🎜 Ci-dessous, nous utilisons un exemple complet pour démontrer comment utiliser gRPC pour implémenter la transmission simultanée de données dans Golang. 🎜🎜Tout d'abord, nous devons ajouter le code suivant dans server/main.go : 🎜rrreee🎜Ensuite, ajoutez le code suivant dans client/main.go : 🎜rrreee🎜Enfin, nous pouvons exécuter la commande suivante dans le répertoire racine du projet pour démarrer le serveur et le client : 🎜rrreee🎜Les résultats d'exécution sont les suivants : 🎜rrreee🎜On peut voir que le serveur a reçu avec succès la demande du client et a renvoyé les données traitées. 🎜🎜Résumé : 🎜Cet article présente les meilleures pratiques sur la façon d'utiliser gRPC pour implémenter le transfert de données simultané dans Golang. En créant une structure de projet appropriée, en créant des connexions, en implémentant des interfaces de service et en démarrant des services, nous pouvons facilement utiliser gRPC pour la transmission simultanée de données. J'espère que cet article pourra aider les développeurs qui utilisent ou utiliseront gRPC. 🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!