Invoca con gRPC

En esta página, se muestran detalles específicos de Knative serving para desarrolladores que desean usar gRPC para conectar un servicio de Knative serving con otros servicios, por ejemplo, para proporcionar una comunicación simple y de alto rendimiento entre microservicios internos. Knative serving admite llamadas de gRPC unarias y de transmisión.

gRPC unario

En una llamada RPC unaria, el cliente envía una sola solicitud al servidor y obtiene una sola respuesta, similar a una llamada a función normal:
rpc SayHello(HelloRequest) returns (HelloResponse);

gRPC de transmisión

Las siguientes opciones de transmisión están disponibles con gRPC. RPC de transmisión del servidor en las que el cliente envía una solicitud al servidor y obtiene una transmisión para leer que contiene una secuencia de mensajes. El cliente lee la transmisión que se muestra hasta que no haya más mensajes.

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

RPC de transmisión del cliente en las que el cliente escribe una secuencia de mensajes y los envía al servidor en una transmisión. Una vez que el cliente termina de escribir los mensajes, espera a que el servidor muestre la respuesta.

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

RPC de transmisión bidireccional en las que el cliente y el servidor envían mensajes en dos transmisiones de lectura y escritura que operan de forma independiente.

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

Entre los casos prácticos, se incluyen los siguientes:

  • Comunicación entre microservicios internos
  • Cargas altas de datos (gRPC usa búferes de protocolo, que son hasta siete veces más rápidos que las llamadas de REST).
  • Solo se necesita una definición de servicio simple; no es necesario que escribas una biblioteca cliente completa

Para integrar el servicio a gRPC, sigue estos pasos:

  • Define los mensajes y las respuestas de la solicitud en un archivo proto y compílalos.
  • Crea un servidor de gRPC para administrar las solicitudes y mostrar las respuestas: debe escuchar la variable de entorno PORT.
  • Crea un cliente que envíe solicitudes y administre respuestas desde el servidor de gRPC.
  • De manera opcional, agrega autenticación.
  • Compila y, luego, implementa el servicio.

Define y compila mensajes en un archivo proto

No hay elementos adicionales ni específicos de Knative serving para agregar a las definiciones de proto. Como con cualquier otro uso de gRPC, usa búferes de protocolo de gRPC para las definiciones de servicios y la serialización de datos.

Crea un cliente de gRPC

No hay elementos adicionales ni específicos de Knative serving para agregar a un cliente que usa gRPC. Sigue los documentos de gRPC acerca del uso de definiciones de servicios en el código del cliente y los clientes de muestra proporcionados en los instructivos de gRPC específicos del lenguaje.

Escucha las solicitudes de gRPC en un servicio de Knative serving

El único requisito especial para un servidor de gRPC que se ejecuta en Knative serving es escuchar en el puerto que la variable de entorno PORT especificó como se muestra en el código:

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

Abre una conexión de gRPC a un servicio

Para abrir una conexión de gRPC a un servicio a fin de que puedas enviar mensajes de gRPC, debes especificar el dominio del host, que es la URL del servicio de Knative serving o el dominio personalizado que se asignó a ese servicio, junto con el puerto 443, que es el que se espera que use 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 {
		// 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...)
}

Envía solicitudes de gRPC sin autenticación

En el siguiente ejemplo, se muestra cómo enviar una solicitud sin autenticación mediante una conexión de gRPC que se configuró como se mencionó antes.

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