Invoca con gRPC

En esta página, se muestran detalles específicos de la entrega de Knative para los desarrolladores que desean usar gRPC a fin de conectar un servicio de entrega de Knative con otros servicios, por ejemplo, para proporcionar una comunicación simple y de alto rendimiento entre microservicios internos. La entrega de Knative 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 única 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 o Knative que entreguen elementos específicos para agregar a tus 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 servicios adicionales ni Knative que se puedan agregar a un cliente que usa gRPC. Sigue los documentos de gRPC sobre el uso de definiciones de servicios en el código del cliente y los clientes de muestra que se proporcionan en los instructivos de gRPC específicos del lenguaje.

Escucha las solicitudes de gRPC en un servicio de entrega de Knative

El único requisito especial para un servidor de gRPC que se ejecuta en la entrega de Knative es escuchar en el puerto que especifica la variable de entorno PORT 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 de modo que puedas enviar mensajes de gRPC, debes especificar el dominio de host, que es la URL del servicio de entrega de Knative o el dominio personalizado asignado a ese servicio, junto con el puerto 443, que es el puerto 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)
}