Utilizzo di gRPC

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Questa pagina mostra i dettagli specifici di Cloud Run per gli sviluppatori che vogliono utilizzare gRPC per connettere un servizio Cloud Run ad altri servizi, ad esempio per fornire comunicazioni semplici e ad alte prestazioni tra i microservizi interni. Con Cloud Run puoi utilizzare tutti i tipi di gRPC, con flussi di dati o unario.

I possibili casi d'uso includono:

  • Comunicazione tra microservizi interni.
  • Carichi di dati elevati (gRPC utilizza buffer di protocollo, fino a sette volte più veloci delle chiamate REST).
  • È necessaria solo una definizione del servizio semplice, non vuoi scrivere una libreria client completa.
  • Utilizza i flussi di dati gRPC in streaming nel server gRPC per creare applicazioni e API più adattabili.

Per integrare il tuo servizio con gRPC,

  • Configura il tuo servizio per l'utilizzo di HTTP/2 se utilizzi lo streaming gRPC. HTTP/2 è il metodo di trasporto per lo streaming gRPC.
  • Definisci i messaggi di richiesta e le risposte in un file protocollo e compilali.
  • Crea un server gRPC per gestire le richieste e restituire le risposte: deve rimanere in ascolto della variabile di ambiente PORT.
  • Crea un client che invii richieste e gestisca le risposte del server gRPC.
  • In via facoltativa, aggiungi l'autenticazione.
  • Crea ed esegui il deployment del tuo servizio.

Configurazione del servizio per l'utilizzo di HTTP/2

Google consiglia di configurare il servizio in modo da utilizzare HTTP/2 se utilizzi gRPC con Cloud Run. Sebbene alcune semplici funzionalità gRPC funzionino senza utilizzare HTTP/2, molte funzionalità gRPC, come lo streaming e i metadati, richiedono HTTP/2.

Definizione e compilazione dei messaggi in un file protocollo

Non sono presenti ulteriori elementi specifici o Cloud Run da aggiungere alle definizioni di protocollo. Come per qualsiasi altro utilizzo di gRPC, utilizzi i buffer di protocollo gRPC per le definizioni dei servizi e la serializzazione dei dati.

Creazione di un client gRPC

Non ci sono elementi aggiuntivi o specifici di Cloud Run da aggiungere a un client che utilizza gRPC: segui i documenti gRPC sull'utilizzo delle definizioni dei servizi nel codice client e i client di esempio forniti nei tutorial gRPC specifici del linguaggio.

In ascolto di richieste gRPC in un servizio Cloud Run

L'unico requisito speciale per un server gRPC in esecuzione in Cloud Run è l'ascolto della porta specificata dalla variabile di ambiente PORT, come mostrato nel codice:

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)
	}
}

Apertura di una connessione gRPC a un servizio

Per aprire una connessione gRPC a un servizio in modo da poter inviare messaggi gRPC, devi specificare il dominio host, che è l'URL del servizio Cloud Run o il dominio personalizzato associato a tale servizio, insieme alla porta 443, che è la porta che dovrebbe essere utilizzata da 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...)
}

Inviare richieste gRPC senza autenticazione

Il seguente esempio mostra come inviare una richiesta senza autenticazione utilizzando una connessione gRPC configurata come accennato in precedenza.

Go


import (
	"context"
	"time"

	pb "github.com/GoogleCloudPlatform/golang-samples/run/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)
}

Inviare richieste gRPC con autenticazione

L'esempio seguente mostra come utilizzare l'autenticazione tra i servizi, se il servizio di chiamata ha l'autorizzazione di callback per il servizio di destinazione. Tieni presente che questo codice crea un'intestazione di autorizzazione con il token di identità appropriato: è obbligatorio. Le autorizzazioni richieste e l'intestazione dell'autorizzazione sono descritte in dettaglio nell'autenticazione da servizio a servizio.

Go


import (
	"context"
	"fmt"
	"time"

	"google.golang.org/api/idtoken"
	"google.golang.org/grpc"
	grpcMetadata "google.golang.org/grpc/metadata"

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

// pingRequestWithAuth mints a new Identity Token for each request.
// This token has a 1 hour expiry and should be reused.
// audience must be the auto-assigned URL of a Cloud Run service or HTTP Cloud Function without port number.
func pingRequestWithAuth(conn *grpc.ClientConn, p *pb.Request, audience string) (*pb.Response, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// Create an identity token.
	// With a global TokenSource tokens would be reused and auto-refreshed at need.
	// A given TokenSource is specific to the audience.
	tokenSource, err := idtoken.NewTokenSource(ctx, audience)
	if err != nil {
		return nil, fmt.Errorf("idtoken.NewTokenSource: %v", err)
	}
	token, err := tokenSource.Token()
	if err != nil {
		return nil, fmt.Errorf("TokenSource.Token: %v", err)
	}

	// Add token to gRPC Request.
	ctx = grpcMetadata.AppendToOutgoingContext(ctx, "authorization", "Bearer "+token.AccessToken)

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

Codice di esempio per lo streaming gRPC

Per un codice campione, fai riferimento all'implementazione di RouteGuide nel tutorial gRPC Basics per il linguaggio che preferisci. Ad esempio, per Go, consulta Implementare RouteGuide.