Appeler avec gRPC

Cette page présente des détails spécifiques à Cloud Run pour Anthos sur Google Cloud pour les développeurs qui souhaitent connecter un service Cloud Run pour Anthos à d'autres services à l'aide de gRPC, par exemple pour assurer une communication simple hautes performances entre des microservices internes. Cloud Run pour Anthos sur Google Cloud accepte les appels gRPC unaires et en streaming.

gRPC unaire

Dans un appel RPC unaire, le client envoie une seule requête au serveur et reçoit une seule réponse, d'une manière semblable à un appel de fonction normal :
rpc SayHello(HelloRequest) returns (HelloResponse);

Streaming gRPC

Les options de streaming suivantes sont disponibles avec gRPC. Les RPC de streaming de serveur, où le client envoie une requête au serveur et obtient un flux à lire, qui contient une séquence de messages. Le client lit le flux renvoyé jusqu'à ce qu'il n'y ait plus de messages.

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

Les RPC de streaming de client, où le client écrit une séquence de messages et l'envoie au serveur dans un flux. Une fois que le client a terminé d'écrire des messages, il attend que le serveur renvoie sa réponse.

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

Les RPC de streaming bidirectionnel, où le client et le serveur envoient des messages dans deux flux en lecture-écriture qui fonctionnent indépendamment.

rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);

Voici des exemples d'utilisation possible :

  • Communication entre des microservices internes.
  • Charges de données élevées (gRPC utilise des tampons de protocole, qui sont jusqu'à sept fois plus rapides que les appels REST).
  • Seule une définition de service simple est nécessaire, vous n'avez pas besoin d'écrire une bibliothèque cliente complète.

Pour intégrer votre service à gRPC, procédez comme suit :

  • Définissez les messages de requête et les réponses dans un fichier proto, puis compilez-les.
  • Créez un serveur gRPC pour gérer les requêtes et renvoyer des réponses : il doit écouter la variable d'environnement PORT.
  • Créez un client qui envoie des requêtes et gère les réponses du serveur gRPC.
  • Vous pouvez éventuellement ajouter une authentification.
  • Créez et déployez votre service.

Définir et compiler des messages dans un fichier proto

Vous n'avez pas besoin d'ajouter d'éléments supplémentaires ou propres à Cloud Run pour Anthos à vos définitions proto. Comme pour toute autre utilisation de gRPC, vous utilisez des tampons de protocole gRPC pour les définitions de service et la sérialisation des données.

Créer un client gRPC

Vous n'avez pas besoin d'ajouter d'éléments supplémentaires ou propres à Cloud Run pour Anthos à un client qui utilise gRPC : suivez les documents gRPC sur l'utilisation des définitions de service dans le code client et les exemples de clients fournis dans les tutoriels gRPC propres aux différents langages.

Écouter les requêtes gRPC dans un service Cloud Run pour Anthos

La seule condition requise pour un serveur gRPC exécuté dans Cloud Run pour Anthos est d'écouter le port spécifié par la variable d'environnement PORT, comme indiqué dans le code :

Go

func main() {
	log.Printf("grpc-ping: starting server...")

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
		log.Printf("Defaulting to port %s", port)
	}

	listener, err := net.Listen("tcp", ":"+port)
	if err != nil {
		log.Fatalf("net.Listen: %v", err)
	}

	grpcServer := grpc.NewServer()
	pb.RegisterPingServiceServer(grpcServer, &pingService{})
	if err = grpcServer.Serve(listener); err != nil {
		log.Fatal(err)
	}
}

Ouvrir une connexion gRPC à un service

Pour ouvrir une connexion gRPC à un service afin de pouvoir envoyer des messages gRPC, vous devez spécifier le domaine hôte, qui correspond à l'URL du service Cloud Run pour Anthos ou au domaine personnalisé mappé à ce service, ainsi que le port 443, qui est censé être utilisé par gRPC.

Go


import (
	"crypto/tls"
	"crypto/x509"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

// NewConn creates a new gRPC connection.
// host should be of the form domain:port, e.g., example.com:443
func NewConn(host string, insecure bool) (*grpc.ClientConn, error) {
	var opts []grpc.DialOption
	if host != "" {
		opts = append(opts, grpc.WithAuthority(host))
	}

	if insecure {
		opts = append(opts, grpc.WithInsecure())
	} else {
		systemRoots, err := x509.SystemCertPool()
		if err != nil {
			return nil, err
		}
		cred := credentials.NewTLS(&tls.Config{
			RootCAs: systemRoots,
		})
		opts = append(opts, grpc.WithTransportCredentials(cred))
	}

	return grpc.Dial(host, opts...)
}

Envoyer des requêtes gRPC sans authentification

L'exemple suivant montre comment envoyer une requête sans authentification, à l'aide d'une connexion gRPC configurée comme indiqué précédemment.

Go


import (
	"context"
	"time"

	pb "github.com/GoogleCloudPlatform/golang-samples/kuberun/grpc-ping/pkg/api/v1"
	"google.golang.org/grpc"
)

// pingRequest sends a new gRPC ping request to the server configured in the connection.
func pingRequest(conn *grpc.ClientConn, p *pb.Request) (*pb.Response, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	client := pb.NewPingServiceClient(conn)
	return client.Send(ctx, p)
}