Como usar o gRPC

Nesta página, mostramos detalhes específicos do Cloud Run para desenvolvedores que querem usar o gRPC para conectar um serviço do Cloud Run a outros serviços, por exemplo, para fornecer uma comunicação simples e de alto desempenho entre microsserviços internos. É possível usar todos os tipos de gRPC, streaming ou unary, com o Cloud Run.

Os possíveis casos de uso incluem:

  • Comunicação entre microsserviços internos.
  • Altas cargas de dados (o gRPC usa buffers de protocolo (em inglês), que são até sete vezes mais rápidos do que as chamadas REST).
  • Basta uma única definição de serviço simples. Não é necessário escrever uma biblioteca de cliente completa.
  • Use gRPCs de streaming no servidor gRPC para criar aplicativos e APIs mais responsivos.

Para integrar seu serviço ao gRPC:

  • Configure o serviço para usar HTTP/2 se você estiver usando o gRPC de streaming. HTTP/2 é o método de transporte para streaming de gRPC.
  • Defina as mensagens de solicitação e as respostas em um arquivo proto e compile-as.
  • Crie um servidor gRPC para processar solicitações e retornar respostas: ele precisa detectar a variável de ambiente PORT.
  • Crie um cliente que envie solicitações e processe respostas do servidor gRPC.
  • Como opção, adicione uma autenticação.
  • Crie e implante seu serviço.

Como configurar o serviço para usar HTTP/2

Se você estiver usando o gRPC de streaming, configure o serviço para usar HTTP/2.

Como definir e compilar mensagens em um arquivo proto

Não há itens extras ou específicos do Cloud Run para adicionar às suas definições de proto. Assim como qualquer outro uso do gRPC, você usa buffers de protocolo gRPC para definições de serviço e serialização de dados.

Como criar um cliente gRPC

Não há itens extras ou específicos do Cloud Run para adicionar a um cliente que usa o gRPC: siga os documentos do gRPC sobre como usar definições de serviço no código do cliente e os clientes de amostra fornecidos no Tutoriais do gRPC específicos de linguagem.

Como detectar solicitações gRPC em um serviço do Cloud Run

O único requisito especial para um servidor gRPC em execução no Cloud Run é detectar a porta especificada pela variável de ambiente PORT, conforme mostrado no 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)
	}
}

Como abrir uma conexão gRPC com um serviço

Para abrir uma conexão gRPC com um serviço e enviar mensagens gRPC, especifique o domínio do host, que é o URL do serviço do Cloud Run ou o domínio personalizado mapeado para esse serviço. a porta 443, que é a porta esperada para ser usada pelo 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...)
}

Como enviar solicitações gRPC sem autenticação

No exemplo a seguir, mostramos como enviar uma solicitação sem autenticação, usando uma conexão gRPC configurada conforme mencionado anteriormente.

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

Como enviar solicitações gRPC com autenticação

No exemplo a seguir, mostramos como usar a autenticação entre serviços, se o serviço de chamada tiver permissão de invocador para o serviço de recebimento. Observe que esse código cria um cabeçalho de autorização que tem o token de identidade adequado: isso é obrigatório. As permissões necessárias e o cabeçalho de autorização estão descritos em detalhes na autenticação de serviço a serviço.

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

Código de amostra para streaming gRPC

Para ver um código de amostra, consulte a implementação de RouteGuide no tutorial do básico do gRPC da linguagem que você escolher. Por exemplo, para Go, consulte Como implementar o RouteGuide.