Mit gRPC aufrufen

Diese Seite enthält spezifische Informationen zu Knative für die Bereitstellung von Entwicklern, die gRPC verwenden möchten, um einen Knative-Bereitstellungsdienst mit anderen Diensten zu verbinden, um beispielsweise eine einfache Hochleistungskommunikation zwischen internen Mikrodiensten zu ermöglichen. Die Knative-Bereitstellung unterstützt sowohl unäre als auch Streaming-gRPC-Aufrufe.

gRPC Unary

Bei einem unären RPC-Aufruf sendet der Client eine einzelne Anfrage an den Server und erhält eine einzelne Antwort zurück, ähnlich wie bei einem normalen Funktionsaufruf:
rpc SayHello(HelloRequest) returns (HelloResponse);

gRPC-Streaming

Die folgenden Streamingoptionen sind mit gRPC verfügbar. Server-Streaming-RPCs, bei denen der Client eine Anfrage an den Server sendet und einen zu lesenden Stream mit einer Reihe von Nachrichten erhält. Der Client liest den zurückgegebenen Stream, bis keine Nachrichten mehr vorhanden sind.

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

Client-Streaming-RPCs, bei denen der Client eine Reihe von Nachrichten schreibt und sie in einem Stream an den Server sendet. Nachdem der Client mit dem Schreiben von Nachrichten fertig ist, wartet er auf die Antwort des Servers.

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

Bidirektionale Streaming-RPCs, bei denen Client und Server Nachrichten in zwei unabhängig arbeitenden Lese-/Schreibstreams senden.

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

Mögliche Anwendungsfälle:

  • Kommunikation zwischen internen Mikrodiensten.
  • Hohe Datenmengen (gRPC verwendet Protokollzwischenspeicher, die bis zu siebenmal schneller sind als REST-Aufrufe).
  • Es wird nur eine einfache Dienstdefinition benötigt. Das Schreiben einer vollständigen Clientbibliothek ist nicht erforderlich.

So binden Sie Ihren Dienst in gRPC ein:

  • Definieren Sie die Anfragenachrichten und -antworten in einer proto-Datei und kompilieren Sie sie.
  • Erstellen Sie einen gRPC-Server, der Anfragen verarbeitet und Antworten zurückgibt. Er sollte die Umgebungsvariable PORT beobachten.
  • Erstellen Sie einen Client, der Anfragen sendet und Antworten vom gRPC-Server verarbeitet.
  • Optional können Sie eine Authentifizierung hinzufügen.
  • Erstellen Sie Ihren Dienst und stellen Sie ihn bereit.

Nachrichten in einer proto-Datei definieren und kompilieren

Sie müssen Ihren Prototypen keine zusätzlichen oder spezifischen Elemente hinzufügen, die Knative bereitstellen. Wie bei jedem anderen Einsatz von gRPC verwenden Sie für Dienstdefinitionen und Datenserialisierung gRPC-Protokollpuffer.

gRPC-Client erstellen

Einem Client, der gRPC verwendet, müssen keine zusätzlichen oder Knative für die Bereitstellung spezifischen Elemente hinzugefügt werden. Folgen Sie der gRPC-Dokumentation zur Verwendung von Dienstdefinitionen im Clientcode und den Beispielclients in den sprachspezifischen gRPC-Anleitungen.

gRPC-Anfragen in einem Knative-Bereitstellungsdienst überwachen

Die einzige spezielle Anforderung an einen gRPC-Server, der in Knative-Bereitstellung ausgeführt wird, besteht darin, den von der Umgebungsvariable PORT angegebenen Port zu überwachen, wie im Code gezeigt:

Einfach loslegen (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)
	}
}

gRPC-Verbindung zu einem Dienst öffnen

Um eine gRPC-Verbindung zu einem Dienst zu öffnen, damit Sie gRPC-Nachrichten senden können, müssen Sie die Hostdomain angeben. Dies ist die URL des Knative-Bereitstellungsdienstes oder die benutzerdefinierte Domain, die diesem Dienst zugeordnet ist, sowie Port 443, der von gRPC erwartet wird.

Einfach loslegen (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 {
		// 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...)
}

gRPC-Anfragen ohne Authentifizierung senden

Im folgenden Beispiel wird gezeigt, wie eine Anfrage ohne Authentifizierung über eine gRPC-Verbindung gesendet wird, die wie oben beschrieben konfiguriert ist.

Einfach loslegen (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)
}