Richiamo con gRPC

Questa pagina mostra dettagli specifici per Knative serving per gli sviluppatori che utilizzare gRPC per connettere un Knative serving con altri servizi, ad esempio per fornire una comunicazione semplice e ad alte prestazioni di microservizi. Knative serving supporta sia le chiamate gRPC unitarie sia quelle di streaming.

gRPC unario

In una chiamata RPC unaria, il client invia una singola richiesta al server e riceve una singola risposta, in modo simile a una normale chiamata di funzione:
rpc SayHello(HelloRequest) returns (HelloResponse);

Streaming gRPC

Con gRPC sono disponibili le seguenti opzioni di streaming. RPC a livello di server in cui il client invia una richiesta al server e riceve un flusso di dati da leggere contenente una sequenza di messaggi. Il client legge i dati restituiti un flusso di dati finché non ci sono più messaggi.

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

RPC di streaming client in cui il client scrive una sequenza di messaggi e li invia al server in uno stream. Dopo che il client ha finito di scrivere i messaggi, attende che il server restituisca la sua risposta.

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

RPC bidirezionali in cui il client e il server inviano i messaggi in due in modalità di lettura/scrittura che operano in modo indipendente.

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

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 semplice definizione di servizio, non è necessario scrivere una biblioteca client completa.

Per integrare il tuo servizio con gRPC,

  • Definisci i messaggi di richiesta e le risposte in un file proto e compilali.
  • Crea un server gRPC per gestire le richieste e restituire le risposte: deve ascoltare la variabile di ambiente PORT.
  • Crea un client che invia richieste e gestisce le risposte del server gRPC.
  • Se vuoi, aggiungi l'autenticazione.
  • Crea ed esegui il deployment del tuo servizio.

Definizione e compilazione di messaggi in un file proto

Non sono disponibili elementi aggiuntivi o elementi specifici di Knative serving da aggiungere al protocollo. le tue definizioni. Proprio come con qualsiasi altro utilizzo di gRPC, Buffer di protocollo gRPC per le definizioni dei servizi e la serializzazione dei dati.

Creazione di un client gRPC

Non sono presenti elementi aggiuntivi o specifici di Knative da aggiungere a un client che utilizza gRPC: segui le indicazioni riportate nella documentazione di gRPC sull'utilizzo delle definizioni di servizio nel codice client e i client di esempio forniti nei tutorial gRPC specifici per ogni linguaggio.

In ascolto di richieste gRPC in un servizio Knative serving

L'unico requisito speciale per un server gRPC in esecuzione in Knative serving è ascoltare sulla porta specificata dalla variabile di ambiente PORT come mostrato nel codice:

Vai

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 avere per specificare il dominio host, ovvero l'URL del servizio Knative serving o il dominio personalizzato mappato a quel servizio, insieme alla porta 443, che si prevede venga utilizzata da gRPC.

Vai


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 {
		// Note: On the Windows platform, use of x509.SystemCertPool() requires
		// go version 1.18 or higher.
		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...)
}

Invio di richieste gRPC senza autenticazione

L'esempio seguente mostra come inviare una richiesta senza autenticazione, utilizzando una connessione gRPC configurata come indicato in precedenza.

Vai


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