이 페이지에서는 gRPC를 사용하여 Cloud Run 서비스를 다른 서비스(예: 내부 마이크로서비스 간의 간단하면서 고성능의 통신 제공)와 연결하려는 개발자를 위한 Cloud Run 관련 세부정보를 보여줍니다. Cloud Run으로 모든 gRPC 유형, 스트리밍 또는 단항을 사용할 수 있습니다.
사용 가능한 사용 사례는 다음과 같습니다.
내부 마이크로서비스 간의 통신
대량의 데이터. 이 경우 gRPC는 REST 호출보다 최대 7배 빠른 프로토콜 버퍼를 사용합니다.
간단한 서비스 정의만 필요한 경우에는 전체 클라이언트 라이브러리를 작성하지 않아도 됩니다.
gRPC 서버에서 스트리밍 gRPC를 사용하여 응답형 애플리케이션 및 API를 빌드합니다.
서비스를 gRPC와 통합하려면 다음 안내를 따르세요.
스트리밍 gRPC를 사용하는 경우 HTTP/2를 사용하도록 서비스를 구성합니다. HTTP/2는 gRPC 스트리밍의 전송 방법입니다.
proto 파일에서 요청 메시지와 응답을 정의하고 컴파일합니다.
요청을 처리하고 응답을 반환하는 gRPC 서버를 만듭니다. 이 서버는 PORT 환경 변수를 리슨해야 합니다.
gRPC 서버에서 요청을 보내고 응답을 처리하는 클라이언트를 만듭니다.
원할 경우 인증을 추가합니다.
서비스를 빌드하고 배포합니다.
HTTP/2를 사용하도록 서비스 구성
Cloud Run에 gRPC를 사용하는 경우 HTTP/2를 사용하도록 서비스를 구성하는 것이 좋습니다. 일부 간단한 gRPC 기능은 HTTP/2를 사용하지 않아도 작동하지만 스트리밍 및 메타데이터와 같은 여러 gRPC 기능에 HTTP/2가 필요합니다.
proto 파일에서 메시지 정의 및 컴파일
proto 정의에 추가할 추가 또는 Cloud Run 관련 항목이 없습니다. 다른 용도로 gRPC를 사용할 때와 마찬가지로 서비스 정의 및 데이터 직렬화에는 gRPC 프로토콜 버퍼를 사용합니다.
gRPC 클라이언트 만들기
gRPC를 사용하는 클라이언트에 추가할 추가 또는 Cloud Run 관련 항목이 없습니다. 클라이언트 코드의 서비스 정의 사용에 관한 gRPC 문서나 언어별 gRPC 튜토리얼에 제공된 샘플 클라이언트를 따르세요.
자동 확장 및 부하 분산
Cloud Run은 클라이언트와 Cloud Run 인스턴스 간에 별도의 연결을 유지하는 Google 관리형 부하 분산기를 사용합니다.
gRPC를 사용하면 자동 확장이 다음과 같이 작동합니다.
클라이언트의 gRPC 연결은 에지 부하 분산기에서 종료됩니다. KeepAlive 설정을 조정하면 Cloud Run 인스턴스가 아닌 부하 분산기에 대한 연결에만 영향을 줍니다. 클라이언트는 인스턴스가 삭제될 때 이를 인식하지 못합니다.
수평 축소 중에 부하 분산기는 백엔드 인스턴스가 종료될 때 GOAWAY 메시지를 전송하여 연결을 종료합니다.
수평 확장 중에 부하 분산기는 백엔드 인스턴스에 대해 새 연결을 만듭니다.
이러한 모든 작업은 클라이언트에 투명합니다.
자동 확장 중에 많은 인스턴스가 시작될 수 있으며 클라이언트와 프록시 부하 분산기 간의 단일 연결로 다중화될 수 있습니다.
동시 실행은 메시지의 인스턴스당 최대 동시 요청 수에 따라 결정됩니다. 스트리밍에서 각 스트림은 최대 동시 요청에 대해 한 번만 계산됩니다.
Cloud Run 서비스에서 gRPC 요청 리슨
Cloud Run에서 실행 중인 gRPC 서버에만 적용되는 특별한 요구사항은 다음 코드에 표시된 대로 PORT 환경 변수로 지정된 포트를 리슨해야 한다는 것입니다.
Go
funcmain(){log.Printf("grpc-ping: starting server...")port:=os.Getenv("PORT")ifport==""{port="8080"log.Printf("Defaulting to port %s",port)}listener,err:=net.Listen("tcp",":"+port)iferr!=nil{log.Fatalf("net.Listen: %v",err)}grpcServer:=grpc.NewServer()pb.RegisterPingServiceServer(grpcServer,&pingService{})iferr=grpcServer.Serve(listener);err!=nil{log.Fatal(err)}}
서비스에 대한 gRPC 연결 열기
서비스에 대한 gRPC 연결을 열어 gRPC 메시지를 보내려면 Cloud Run 서비스의 URL 또는 해당 서비스에 매핑된 커스텀 도메인인 호스트 도메인을 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:443funcNewConn(hoststring,insecurebool)(*grpc.ClientConn,error){varopts[]grpc.DialOptionifhost!=""{opts=append(opts,grpc.WithAuthority(host))}ifinsecure{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()iferr!=nil{returnnil,err}cred:=credentials.NewTLS(&tls.Config{RootCAs:systemRoots,})opts=append(opts,grpc.WithTransportCredentials(cred))}returngrpc.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.funcpingRequest(conn*grpc.ClientConn,p*pb.Request)(*pb.Response,error){ctx,cancel:=context.WithTimeout(context.Background(),30*time.Second)defercancel()client:=pb.NewPingServiceClient(conn)returnclient.Send(ctx,p)}
인증과 함께 gRPC 요청 전송
다음 샘플은 호출 서비스에 수신 서비스에 대한 호출자 권한이 있는 경우 서비스 간 인증을 사용하는 방법을 보여줍니다. 이 코드는 적절한 ID 토큰을 가진 승인 헤더를 생성합니다. 이 헤더는 필수입니다. 필수 권한 및 승인 헤더는 서비스 간 인증에 자세히 설명되어 있습니다.
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.funcpingRequestWithAuth(conn*grpc.ClientConn,p*pb.Request,audiencestring)(*pb.Response,error){ctx,cancel:=context.WithTimeout(context.Background(),30*time.Second)defercancel()// 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)iferr!=nil{returnnil,fmt.Errorf("idtoken.NewTokenSource: %w",err)}token,err:=tokenSource.Token()iferr!=nil{returnnil,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)returnclient.Send(ctx,p)}
gRPC 스트리밍용 샘플 코드
샘플 코드는 gRPC 기본 튜토리얼에서 RouteGuide 구현을 원하는 언어로 참조하세요. 예를 들어 Go를 사용할 때는 RouteGuide 구현을 참조하세요.
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["이해하기 어려움","hardToUnderstand","thumb-down"],["잘못된 정보 또는 샘플 코드","incorrectInformationOrSampleCode","thumb-down"],["필요한 정보/샘플이 없음","missingTheInformationSamplesINeed","thumb-down"],["번역 문제","translationIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-07-14(UTC)"],[],[],null,["# Using gRPC\n\nThis page shows Cloud Run-specific details for developers who\nwant to use [gRPC](https://grpc.io/) to connect a\nCloud Run service with other services, for example, to provide\nsimple, high performance communication between internal\nmicroservices. You can use [all gRPC types](https://grpc.io/docs/what-is-grpc/core-concepts#rpc-life-cycle),\nstreaming or unary, with Cloud Run.\n\nPossible use cases include:\n\n- Communication between internal microservices.\n- High loads of data (gRPC uses [protocol buffers](https://developers.google.com/protocol-buffers), which are up to seven times faster than REST calls).\n- Only a simple service definition is needed, you don't want to write a full client library.\n- Use streaming gRPCs in your gRPC server to build more responsive applications and APIs.\n\nTo integrate your service with gRPC:\n\n- Configure your service to use HTTP/2 if you are using streaming gRPC. HTTP/2 is the transport method for gRPC streaming.\n- Define the request messages and responses in a proto file and compile them.\n- Create a gRPC server to handle requests and return responses: it should listen to the `PORT` environment variable.\n- Create a client that sends requests and handles responses from the gRPC server.\n- Optionally, add authentication.\n- Build and deploy your service.\n\nConfiguring your service to use HTTP/2\n--------------------------------------\n\nGoogle recommends [configuring your service to use HTTP/2](/run/docs/configuring/http2) if you\nuse gRPC with Cloud Run. Although some simple gRPC features work\nwithout using HTTP/2, many gRPC features, such as streaming and metadata, require HTTP/2.\n\nDefining and compiling messages in a proto file\n-----------------------------------------------\n\nThere are no extra or Cloud Run-specific things to add to your proto\ndefinitions. Just as with any other use of gRPC, you use\n[gRPC protocol buffers](https://grpc.io/docs/guides/#working-with-protocol-buffers)\nfor service definitions and data serialization.\n\nCreating a gRPC client\n----------------------\n\nThere are no extra or Cloud Run specific things to add to a client\nthat uses gRPC: follow the gRPC docs on using service definitions in\n[client code](https://grpc.io/docs/guides/concepts/#using-the-api), and the\nsample clients provided in the language-specific\n[gRPC tutorials](https://grpc.io/docs/languages).\n\nAutoscaling and load balancing\n------------------------------\n\nCloud Run uses Google-managed load balancers that keep separate\nconnections between clients and your Cloud Run instances.\nWith gRPC, autoscaling behaves as follows:\n\n- gRPC connections from clients end at the edge load balancer. Adjusting `KeepAlive` settings only affects the connection to the load balancer, not the Cloud Run instances. The client doesn't recognize when an instance drops.\n- During scale-in, the load balancer closes connections by sending GOAWAY messages to the backend instances as they shut down.\n- During scale-out, the load balancer creates new connections to the backend instances. All these operations are transparent to clients.\n- During autoscaling, many instances can start up and multiplex into a single connection between the client and the proxy load balancer.\n- Concurrency is determined by the [maximum concurrent requests per instance](/run/docs/about-concurrency) for messages. In streaming, each stream is counted once against the maximum concurrent requests.\n\nListening for gRPC requests in a Cloud Run service\n--------------------------------------------------\n\nThe only special requirement for a gRPC server running in\nCloud Run is to listen at the port specified by the `PORT`\nenvironment variable as shown in the following code:\n\n\n### Go\n\n func main() {\n \tlog.Printf(\"grpc-ping: starting server...\")\n\n \tport := os.Getenv(\"PORT\")\n \tif port == \"\" {\n \t\tport = \"8080\"\n \t\tlog.Printf(\"Defaulting to port %s\", port)\n \t}\n\n \tlistener, err := net.Listen(\"tcp\", \":\"+port)\n \tif err != nil {\n \t\tlog.Fatalf(\"net.Listen: %v\", err)\n \t}\n\n \tgrpcServer := grpc.NewServer()\n \tpb.RegisterPingServiceServer(grpcServer, &pingService{})\n \tif err = grpcServer.Serve(listener); err != nil {\n \t\tlog.Fatal(err)\n \t}\n }\n\n\u003cbr /\u003e\n\nOpening a gRPC connection to a service\n--------------------------------------\n\nTo open a gRPC connection to a service so you can send gRPC messages, you need\nto specify the host domain, which is the URL of the Cloud Run service\nor the custom domain [mapped](/run/docs/mapping-custom-domains) to that service,\nalong with the port 443, which is the port expected to be used by gRPC.\n\n\n### Go\n\n\n import (\n \t\"crypto/tls\"\n \t\"crypto/x509\"\n\n \t\"google.golang.org/grpc\"\n \t\"google.golang.org/grpc/credentials\"\n )\n\n // NewConn creates a new gRPC connection.\n // host should be of the form domain:port, e.g., example.com:443\n func NewConn(host string, insecure bool) (*grpc.ClientConn, error) {\n \tvar opts []grpc.DialOption\n \tif host != \"\" {\n \t\topts = append(opts, grpc.WithAuthority(host))\n \t}\n\n \tif insecure {\n \t\topts = append(opts, grpc.WithInsecure())\n \t} else {\n \t\t// Note: On the Windows platform, use of x509.SystemCertPool() requires\n \t\t// Go version 1.18 or higher.\n \t\tsystemRoots, err := x509.SystemCertPool()\n \t\tif err != nil {\n \t\t\treturn nil, err\n \t\t}\n \t\tcred := credentials.NewTLS(&tls.Config{\n \t\t\tRootCAs: systemRoots,\n \t\t})\n \t\topts = append(opts, grpc.WithTransportCredentials(cred))\n \t}\n\n \treturn grpc.Dial(host, opts...)\n }\n\n\u003cbr /\u003e\n\nSending gRPC requests without authentication\n--------------------------------------------\n\nThe following sample shows how to send a request without authentication, using\na [gRPC connection](#connect) configured as mentioned previously.\n\n\n### Go\n\n\n import (\n \t\"context\"\n \t\"time\"\n\n \tpb \"github.com/GoogleCloudPlatform/golang-samples/run/grpc-ping/pkg/api/v1\"\n \t\"google.golang.org/grpc\"\n )\n\n // pingRequest sends a new gRPC ping request to the server configured in the connection.\n func pingRequest(conn *grpc.ClientConn, p *pb.Request) (*pb.Response, error) {\n \tctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n \tdefer cancel()\n\n \tclient := pb.NewPingServiceClient(conn)\n \treturn client.Send(ctx, p)\n }\n\n\u003cbr /\u003e\n\nSending gRPC requests with authentication\n-----------------------------------------\n\nThe following sample shows how to use authentication between services, if the\ncalling service has invoker permission to the receiving service. Notice that\nthis code creates an authorization header that has the proper identity token:\nthis is required. The required permissions and the authorization header are\ndescribed in detail in\n[service to service authentication](/run/docs/authenticating/service-to-service).\n\n\n### Go\n\n\n import (\n \t\"context\"\n \t\"fmt\"\n \t\"time\"\n\n \t\"google.golang.org/api/idtoken\"\n \t\"google.golang.org/grpc\"\n \tgrpcMetadata \"google.golang.org/grpc/metadata\"\n\n \tpb \"github.com/GoogleCloudPlatform/golang-samples/run/grpc-ping/pkg/api/v1\"\n )\n\n // pingRequestWithAuth mints a new Identity Token for each request.\n // This token has a 1 hour expiry and should be reused.\n // audience must be the auto-assigned URL of a Cloud Run service or HTTP Cloud Function without port number.\n func pingRequestWithAuth(conn *grpc.ClientConn, p *pb.Request, audience string) (*pb.Response, error) {\n \tctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n \tdefer cancel()\n\n \t// Create an identity token.\n \t// With a global TokenSource tokens would be reused and auto-refreshed at need.\n \t// A given TokenSource is specific to the audience.\n \ttokenSource, err := idtoken.NewTokenSource(ctx, audience)\n \tif err != nil {\n \t\treturn nil, fmt.Errorf(\"idtoken.NewTokenSource: %w\", err)\n \t}\n \ttoken, err := tokenSource.Token()\n \tif err != nil {\n \t\treturn nil, fmt.Errorf(\"TokenSource.Token: %w\", err)\n \t}\n\n \t// Add token to gRPC Request.\n \tctx = grpcMetadata.AppendToOutgoingContext(ctx, \"authorization\", \"Bearer \"+token.AccessToken)\n\n \t// Send the request.\n \tclient := pb.NewPingServiceClient(conn)\n \treturn client.Send(ctx, p)\n }\n\n\u003cbr /\u003e\n\nSample code for gRPC streaming\n------------------------------\n\nFor sample code, refer to the `RouteGuide` implementation in the\n[gRPC](https://grpc.io/) Basics tutorial for the\nlanguage of your choice. When using Go, for example, refer to\n[Implementing RouteGuide](https://grpc.io/docs/languages/go/basics/#implementing-routeguide)."]]