Menggunakan gRPC

Halaman ini menampilkan detail khusus Cloud Run untuk developer yang ingin menggunakan gRPC untuk menghubungkan layanan Cloud Run dengan layanan lain, misalnya, untuk memberikan sederhana, komunikasi performa tinggi antara microservice internal. Anda dapat menggunakan semua jenis gRPC, baik streaming maupun unary, dengan Cloud Run.

Kemungkinan kasus penggunaan meliputi:

  • Komunikasi antara microservice internal.
  • Pemuatan data yang tinggi (gRPC menggunakan buffering protokol, yang hingga tujuh kali lebih cepat daripada panggilan REST).
  • Hanya definisi layanan sederhana yang diperlukan, dan Anda tidak ingin menulis library klien secara lengkap.
  • Gunakan gRPC streaming di server gRPC Anda untuk membuat aplikasi dan API yang lebih responsif.

Untuk mengintegrasikan layanan Anda dengan gRPC:

  • Konfigurasi layanan Anda untuk menggunakan HTTP/2 jika menggunakan gRPC streaming. HTTP/2 adalah metode transport untuk streaming gRPC.
  • Tentukan pesan dan respons permintaan dalam file proto, lalu kompilasikan.
  • Buat server gRPC untuk menangani permintaan dan menampilkan respons: server tersebut harus memproses variabel lingkungan PORT.
  • Buat klien yang mengirim permintaan dan menangani respons dari server gRPC.
  • Secara opsional, tambahkan autentikasi.
  • Build dan deploy layanan Anda.

Mengonfigurasi layanan untuk menggunakan HTTP/2

Google merekomendasikan untuk mengonfigurasi layanan agar menggunakan HTTP/2 jika Anda menggunakan gRPC dengan Cloud Run. Meskipun beberapa fitur gRPC sederhana berfungsi tanpa menggunakan HTTP/2, banyak fitur gRPC, seperti streaming dan metadata, memerlukan HTTP/2.

Menentukan dan mengompilasi pesan dalam file proto

Tidak ada hal tambahan atau Cloud Run khusus yang dapat ditambahkan ke definisi proto Anda. Sama seperti penggunaan gRPC lainnya, Anda menggunakan buffering protokol gRPC untuk definisi layanan dan serialisasi data.

Membuat klien gRPC

Tidak ada hal tambahan atau Cloud Run khusus yang perlu ditambahkan ke klien yang menggunakan gRPC: ikuti dokumen gRPC tentang cara menggunakan definisi layanan dalam kode klien, dan contoh klien disediakan dalam tutorial gRPC bahasa khusus.

Penskalaan otomatis dan load balancing

Cloud Run menggunakan load balancer yang dikelola Google yang menjaga koneksi terpisah antara klien dan instance Cloud Run Anda. Dengan gRPC, penskalaan otomatis berperilaku sebagai berikut:

  • Koneksi gRPC dari klien berakhir di load balancer edge. Menyesuaikan setelan KeepAlive hanya memengaruhi koneksi ke load balancer, bukan instance Cloud Run. Klien tidak mengenali saat instance dihapus.
  • Selama penskalaan, load balancer menutup koneksi dengan mengirim pesan GOAWAY ke instance backend saat dimatikan.
  • Selama penskalaan keluar, load balancer membuat koneksi baru ke instance backend. Semua operasi ini bersifat transparan bagi klien.
  • Selama penskalaan otomatis, banyak instance dapat dimulai dan dimultipleks menjadi satu koneksi antara klien dan load balancer proxy.
  • Serentak ditentukan oleh permintaan serentak maksimum per instance untuk pesan. Dalam streaming, setiap streaming dihitung sekali terhadap permintaan serentak maksimum.

Memproses permintaan gRPC di layanan Cloud Run

Satu-satunya persyaratan khusus untuk server gRPC yang berjalan di Cloud Run adalah memproses port yang ditentukan oleh variabel lingkungan PORT seperti yang ditunjukkan dalam kode berikut:

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

Membuka koneksi gRPC ke layanan

Untuk membuka koneksi gRPC ke layanan sehingga Anda dapat mengirim pesan gRPC, Anda harus menentukan domain host, yang merupakan URL layanan Cloud Run atau domain kustom yang dipetakan ke layanan tersebut, bersama dengan port 443, yang merupakan port yang diharapkan akan digunakan oleh 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...)
}

Mengirim permintaan gRPC tanpa autentikasi

Contoh berikut menunjukkan cara mengirim permintaan tanpa autentikasi, menggunakan koneksi gRPC yang dikonfigurasi seperti yang disebutkan sebelumnya.

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

Mengirim permintaan gRPC dengan autentikasi

Contoh berikut menunjukkan cara menggunakan autentikasi antar-layanan jika layanan panggilan memiliki izin invoker ke layanan penerima. Perhatikan bahwa kode ini menghasilkan header otorisasi yang memiliki token identitas yang tepat: ini diperlukan. Izin yang diperlukan dan header otorisasi dijelaskan secara mendetail dalam autentikasi layanan ke layanan.

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: %w", err)
	}
	token, err := tokenSource.Token()
	if err != nil {
		return nil, fmt.Errorf("TokenSource.Token: %w", 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)
}

Kode contoh untuk streaming gRPC

Untuk contoh kode, lihat penerapan RouteGuide di tutorial Dasar-Dasar gRPC untuk bahasa pilihan Anda. Misalnya, saat menggunakan Go, lihat Mengimplementasikan RouteGuide.