透過 gRPC 叫用

本頁面提供 Knative Serving 專屬詳細資料,供想使用 gRPC 連線 Knative Serving 服務與其他服務的開發人員參考,例如在內部微服務之間提供簡單的高效能通訊。Knative Serving 支援一元串流 gRPC 呼叫。

gRPC Unary

在 unary RPC 呼叫中,用戶端會向伺服器傳送單一要求,並取得單一回應,類似於一般函式呼叫:
rpc SayHello(HelloRequest) returns (HelloResponse);

gRPC 串流

gRPC 提供下列串流選項: 伺服器串流 RPC:用戶端會將要求傳送至伺服器,並取得可讀取的串流,其中包含一連串訊息。用戶端會讀取傳回的串流,直到沒有更多訊息為止。

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

用戶端串流 RPC,用戶端會寫入一連串訊息,並以串流形式傳送至伺服器。用戶端完成訊息撰寫後,會等待伺服器傳回回應。

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

雙向串流 RPC,用戶端和伺服器會在兩個獨立運作的讀寫串流中傳送訊息。

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

可能的用途包括:

  • 內部微服務之間的通訊。
  • 資料負載量高 (gRPC 使用通訊協定緩衝區,速度比 REST 呼叫快七倍)。
  • 您只需要簡單的服務定義,不需要編寫完整的用戶端程式庫。

如要整合服務與 gRPC,請按照下列步驟操作:

  • 在 proto 檔案中定義要求訊息和回應,然後編譯這些訊息和回應。
  • 建立 gRPC 伺服器來處理要求並傳回回應:伺服器應監聽 PORT 環境變數。
  • 建立用戶端,傳送要求並處理 gRPC 伺服器的回應。
  • 也可以選擇新增驗證。
  • 建構及部署服務。

在 Proto 檔案中定義及編譯訊息

您不需要在 proto 定義中新增額外或 Knative serving 專屬項目。與使用任何其他 gRPC 服務一樣,您可以使用 gRPC 通訊協定緩衝區進行服務定義和資料序列化。

建立 gRPC 用戶端

使用 gRPC 的用戶端不需要額外或 Knative 服務專屬的項目:請按照 gRPC 說明文件,在用戶端程式碼中使用服務定義,以及語言專屬 gRPC 教學課程中提供的範例用戶端。

在 Knative 服務中監聽 gRPC 要求

在 Knative Serving 中執行的 gRPC 伺服器,唯一特殊需求是監聽 PORT 環境變數指定的通訊埠,如以下程式碼所示:

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 連線

如要開啟與服務的 gRPC 連線,以便傳送 gRPC 訊息,您需要指定主機網域,也就是 Knative 服務服務的網址,或是對應至該服務的自訂網域,以及 gRPC 預期使用的通訊埠 443。

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 要求

下列範例說明如何使用先前設定的 gRPC 連線,傳送未經驗證的要求。

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