跳到主要内容

使用 gRPC 连接到其它服务

本页面向希望使用 gRPC 将云托管服务与其它服务连接起来(例如在内部服务直接提供高性能通信)的开发者介绍特定于云托管服务的详细信息。您将可以将所有gRPC类型(流式传输或一元)与云托管结合使用。

可能使用的场景包括:

  • 内部微服务之间的相互通信
  • 在 gRPC 服务器中使用流式传输 gRPC 来构建响应更快的应用和 API。

如需将您的服务与 gRPC 集成,请执行以下操作:

  • 服务设置 -> 网络访问 中开启内网开关,并通过内网域名进行相互访问。
  • 如果使用流式传输 gRPC,将服务配置为使用 HTTP/2。 HTTP/2 是 gRPC 流式传输的传输方法。
  • 在 proto 文件中定义请求消息和响应,并对其进行编译。
  • 创建一个客户端,用于发送请求并处理来自 gRPC 服务器的响应。
  • 构建和部署服务。

监听云托管服务中的 gRPC 请求

云托管中运行的 gRPC 服务器的唯一特殊要求是监听 PORT 环境变量指定的端口,如以下代码所示:

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 消息,需要打开服务的内网开关,获取到内网域名,同时通过 PORT 环境变量只能的端口进行访问, 如下代码所示:


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 连接来发送服务请求:


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