728x90
반응형
728x90
반응형
반응형

gRPC 소개

이 페이지에서는 gRPC와 프로토콜 버퍼를 소개합니다. gRPC는 프로토콜 버퍼를 인터페이스 정의 언어( IDL )와 기본 메시지 교환 형식으로 사용할 수 있습니다. gRPC 및/또는 프로토콜 버퍼를 처음 사용하는 경우 이 글을 읽어보세요! 먼저 gRPC를 실행해 보고 싶다면 언어를 선택하고 빠른 시작을 시도해 보세요 .

개요

gRPC에서 클라이언트 애플리케이션은 마치 로컬 객체인 것처럼 다른 머신의 서버 애플리케이션에서 메서드를 직접 호출할 수 있으므로 분산 애플리케이션과 서비스를 더 쉽게 만들 수 있습니다. 많은 RPC 시스템에서와 마찬가지로 gRPC는 서비스를 정의하고 매개변수와 반환 유형으로 원격으로 호출할 수 있는 메서드를 지정하는 아이디어를 기반으로 합니다. 서버 측에서 서버는 이 인터페이스를 구현하고 클라이언트 호출을 처리하기 위해 gRPC 서버를 실행합니다. 클라이언트 측에서 클라이언트는 서버와 동일한 메서드를 제공하는 스텁(일부 언어에서는 단순히 클라이언트라고 함)을 갖습니다.

gRPC 클라이언트와 서버는 다양한 환경에서 실행되고 서로 통신할 수 있습니다. Google 내부 서버에서 사용자 데스크톱까지, 그리고 gRPC에서 지원하는 모든 언어로 작성할 수 있습니다. 예를 들어, Go, Python 또는 Ruby 클라이언트가 있는 Java로 gRPC 서버를 쉽게 만들 수 있습니다. 또한 최신 Google API에는 인터페이스의 gRPC 버전이 있어 애플리케이션에 Google 기능을 쉽게 빌드할 수 있습니다.

프로토콜 버퍼 작업

기본적으로 gRPC는 프로토콜 버퍼를 사용합니다., 구조화된 데이터를 직렬화하기 위한 Google의 성숙한 오픈 소스 메커니즘(JSON과 같은 다른 데이터 형식과 함께 사용할 수 있음). 작동 방식에 대한 간단한 소개가 있습니다. 이미 프로토콜 버퍼에 익숙하다면 다음 섹션으로 건너뛰어도 됩니다.

프로토콜 버퍼로 작업할 때 첫 번째 단계는 proto 파일 에서 직렬화하려는 데이터의 구조를 정의하는 것입니다 . 이는 확장자가 있는 일반 텍스트 파일입니다 . 프로토콜 버퍼 데이터는 메시지.proto 로 구조화되며 , 각 메시지는 필드 라고 하는 일련의 이름-값 쌍을 포함하는 정보의 작은 논리적 레코드입니다 . 간단한 예는 다음과 같습니다.

message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}

그런 다음 데이터 구조를 지정했으면 프로토콜 버퍼 컴파일러를 사용하여 protoc proto 정의에서 선호하는 언어로 데이터 액세스 클래스를 생성합니다. 이는 name() 및 와 같은 각 필드에 대한 간단한 접근자 set_name()와 전체 구조를 원시 바이트로 직렬화/파싱하는 메서드를 제공합니다. 예를 들어 선택한 언어가 C++인 경우 위의 예에서 컴파일러를 실행하면 Person 라는 클래스가 생성됩니다. 그런 다음 이 클래스를 애플리케이션에서 사용하여 프로토콜 버퍼 메시지를 채우고, 직렬화하고, 검색할 수 있습니다.

일반 proto 파일에서 gRPC 서비스를 정의하고 RPC 메서드 매개변수와 반환 유형을 프로토콜 버퍼 메시지로 지정합니다.

// The greeter service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

gRPC는 protoc특수 gRPC 플러그인과 함께 사용하여 proto 파일에서 코드를 생성합니다. 생성된 gRPC 클라이언트 및 서버 코드와 메시지 유형을 채우고, 직렬화하고, 검색하기 위한 일반 프로토콜 버퍼 코드를 얻습니다. protoc선택한 언어로 gRPC 플러그인을 사용하여 설치하는 방법을 포함하여 프로토콜 버퍼에 대해 자세히 알아보려면 프로토콜 버퍼 설명서를 참조하세요.

프로토콜 버퍼 버전

프로토콜 버퍼s는 오픈 소스 사용자에게 한동안 제공되어 왔으며, 이 사이트의 대부분 예제는 프로토콜 버퍼 버전 3(proto3)을 사용합니다. 이 버전은 구문이 약간 간소화되었고, 몇 가지 유용한 새로운 기능이 있으며, 더 많은 언어를 지원합니다. Proto3는 현재 Java, C++, Dart, Python, Objective-C, C#, 라이트 런타임(Android Java), Ruby, JavaScript에서 프로토콜 버퍼 GitHub 리포지토리 에서 제공됩니다. golang/protobuf 공식 패키지 의 Go 언어 생성기뿐만 아니라, 더 많은 언어가 개발 중입니다. 자세한 내용은 proto3 언어 가이드 에서 확인할 수 있습니다.그리고 참조 문서각 언어에 대해 사용 가능합니다. 참조 문서에는 공식 사양도 포함되어 있습니다. 파일 형식 .proto.

일반적으로 proto2(현재 기본 프로토콜 버퍼 버전)를 사용할 수도 있지만, proto3를 gRPC와 함께 사용하는 것이 좋습니다. proto3를 사용하면 gRPC에서 지원하는 모든 언어를 사용할 수 있고 proto2 클라이언트와 proto3 서버 간에 통신하는 경우와 그 반대의 경우의 호환성 문제를 피할 수 있습니다.

핵심 개념, 아키텍처 및 라이프사이클

gRPC 아키텍처와 RPC 수명 주기를 개요로 설명하며, 주요 gRPC 개념을 소개합니다.

gRPC에 익숙하지 않으신가요? 먼저 gRPC 소개를 읽어보세요. 언어별 세부 정보는 선택한 언어에 대한 빠른 시작, 튜토리얼 및 참조 문서를 참조하세요.

개요

서비스 정의

많은 RPC 시스템과 마찬가지로 gRPC는 서비스를 정의하고 매개변수와 반환 유형으로 원격으로 호출할 수 있는 메서드를 지정하는 아이디어를 기반으로 합니다. 기본적으로 gRPC는 프로토콜 버퍼를 사용합니다.서비스 인터페이스와 페이로드 메시지의 구조를 모두 설명하는 인터페이스 정의 언어(IDL)로 사용됩니다. 원하는 경우 다른 대안을 사용할 수 있습니다.

service HelloService {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}

gRPC를 사용하면 네 가지 종류의 서비스 방법을 정의할 수 있습니다.

  • 클라이언트가 서버에 단일 요청을 보내고 일반 함수 호출처럼 단일 응답을 받는 단항 RPC입니다.
rpc SayHello(HelloRequest) returns (HelloResponse);
  • 클라이언트가 서버에 요청을 보내고 스트림을 받아 일련의 메시지를 다시 읽는 서버 스트리밍 RPC. 클라이언트는 더 이상 메시지가 없을 때까지 반환된 스트림에서 읽습니다. gRPC는 개별 RPC 호출 내에서 메시지 순서를 보장합니다.
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
  • 클라이언트가 일련의 메시지를 작성하여 제공된 스트림을 사용하여 서버로 보내는 클라이언트 스트리밍 RPC입니다. 클라이언트가 메시지 작성을 마치면 서버가 메시지를 읽고 응답을 반환할 때까지 기다립니다. 다시 말해 gRPC는 개별 RPC 호출 내에서 메시지 순서를 보장합니다.
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
  • 양쪽이 읽기-쓰기 스트림을 사용하여 일련의 메시지를 보내는 양방향 스트리밍 RPC. 두 스트림은 독립적으로 작동하므로 클라이언트와 서버는 원하는 순서대로 읽고 쓸 수 있습니다. 예를 들어, 서버는 응답을 쓰기 전에 모든 클라이언트 메시지를 수신할 때까지 기다리거나, 메시지를 읽고 쓰기를 번갈아가며 하거나, 읽기와 쓰기를 조합할 수 있습니다. 각 스트림의 메시지 순서는 유지됩니다.
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);

아래의 RPC 수명 주기 섹션 에서 다양한 유형의 RPC에 대해 자세히 알아볼 수 있습니다.

API 사용하기

gRPC는 파일 에서 서비스 정의를 시작으로 .proto 클라이언트와 서버 측 코드를 생성하는 프로토콜 버퍼 컴파일러 플러그인을 제공합니다. gRPC 사용자는 일반적으로 클라이언트 측에서 이러한 API를 호출하고 서버 측에서 해당 API를 구현합니다.

  • 서버 측에서 서버는 서비스에서 선언한 메서드를 구현하고 클라이언트 호출을 처리하기 위해 gRPC 서버를 실행합니다. gRPC 인프라는 들어오는 요청을 디코딩하고, 서비스 메서드를 실행하고, 서비스 응답을 인코딩합니다.

  • 클라이언트 측에서 클라이언트는 stub (일부 언어의 경우 선호되는 용어는 client )로 알려진 로컬 객체를 가지고 있으며, 이는 서비스와 동일한 메소드를 구현합니다. 그런 다음 클라이언트는 로컬 객체에서 해당 메소드를 호출할 수 있으며, 메소드는 적절한 프로토콜 버퍼 메시지 유형에서 호출에 대한 매개변수를 래핑하고, 요청을 서버로 보내고, 서버의 프로토콜 버퍼 응답을 반환합니다.

동기 vs. 비동기

서버에서 응답이 도착할 때까지 차단되는 동기 RPC 호출은 RPC가 열망하는 프로시저 호출의 추상화에 가장 근접한 것입니다. 반면, 네트워크는 본질적으로 비동기적이며 많은 시나리오에서 현재 스레드를 차단하지 않고 RPC를 시작할 수 있는 것이 유용합니다.

대부분 언어의 gRPC 프로그래밍 API는 동기 및 비동기 플레이버로 제공됩니다. 각 언어의 튜토리얼 및 참조 문서에서 자세한 내용을 확인할 수 있습니다. (전체 참조 문서는 곧 제공될 예정입니다)

RPC 라이프 사이클

이 섹션에서는 gRPC 클라이언트가 gRPC 서버 메서드를 호출할 때 발생하는 일을 자세히 살펴보겠습니다. 전체 구현 세부 정보는 언어별 페이지를 참조하세요.

단항 RPC

먼저, 클라이언트가 단일 요청을 보내고 단일 응답을 받는 가장 간단한 RPC 유형을 생각해 보겠습니다.

  1. 클라이언트가 스텁 메서드를 호출하면, 해당 호출에 대한 클라이언트의 메타데이터, 메서드 이름, 지정된 기한( 해당되는 경우) 과 함께 RPC가 호출되었다는 알림이 서버에 전달됩니다 .

  2. 그런 다음 서버는 자체 초기 메타데이터(응답 전에 보내야 함)를 바로 다시 보내거나 클라이언트의 요청 메시지를 기다릴 수 있습니다. 먼저 발생하는 것은 애플리케이션에 따라 다릅니다.

  3. 서버가 클라이언트의 요청 메시지를 받으면 응답을 만들고 채우는 데 필요한 모든 작업을 수행합니다. 그런 다음 응답은 상태 세부 정보(상태 코드 및 선택적 상태 메시지)와 선택적 후행 메타데이터와 함께 클라이언트에 반환됩니다(성공하는 경우).

  4. 응답 상태가 OK이면 클라이언트는 응답을 받고, 이로써 클라이언트 측에서 호출이 완료됩니다.

서버 스트리밍 RPC

서버 스트리밍 RPC는 단항 RPC와 유사하지만, 서버가 클라이언트의 요청에 응답하여 메시지 스트림을 반환합니다. 모든 메시지를 보낸 후, 서버의 상태 세부 정보(상태 코드 및 선택적 상태 메시지)와 선택적 후행 메타데이터가 클라이언트로 전송됩니다. 이렇게 하면 서버 측에서 처리가 완료됩니다. 클라이언트는 서버의 모든 메시지를 받으면 완료됩니다.

클라이언트 스트리밍 RPC

클라이언트 스트리밍 RPC는 단항 RPC와 비슷하지만 클라이언트가 단일 메시지 대신 메시지 스트림을 서버로 보냅니다. 서버는 단일 메시지(상태 세부 정보와 선택적 후행 메타데이터 포함)로 응답하는데, 일반적으로는 그렇지 않지만 클라이언트의 모든 메시지를 수신한 후에 응답합니다.

양방향 스트리밍 RPC

양방향 스트리밍 RPC에서 호출은 클라이언트가 메서드를 호출하고 서버가 클라이언트 메타데이터, 메서드 이름 및 마감일을 수신하여 시작됩니다. 서버는 초기 메타데이터를 다시 보내거나 클라이언트가 메시지 스트리밍을 시작할 때까지 기다릴 수 있습니다.

클라이언트 및 서버 측 스트림 처리가 애플리케이션에 따라 다릅니다. 두 스트림이 독립적이므로 클라이언트와 서버는 어떤 순서로든 메시지를 읽고 쓸 수 있습니다. 예를 들어, 서버는 클라이언트의 모든 메시지를 수신할 때까지 기다렸다가 메시지를 쓸 수 있고, 서버와 클라이언트는 "핑퐁"을 할 수 있습니다. 즉, 서버가 요청을 받은 다음 응답을 보내고, 클라이언트가 응답에 따라 다른 요청을 보내는 식입니다.

마감일/타임아웃

gRPC를 사용하면 클라이언트가 RPC가 오류로 종료되기 전에 RPC가 완료될 때까지 기다릴 시간을 지정할 수 있습니다 DEADLINE_EXCEEDED. 서버 측에서 서버는 특정 RPC가 시간 초과되었는지 또는 RPC를 완료하기까지 남은 시간이 얼마인지 확인하기 위해 쿼리할 수 있습니다.

마감일이나 시간 초과를 지정하는 것은 언어마다 다릅니다. 일부 언어 API는 시간 초과(시간의 지속 기간)를 기준으로 작동하고, 일부 언어 API는 마감일(고정된 시간 지점)을 기준으로 작동하며 기본 마감일이 있을 수도 있고 없을 수도 있습니다.

RPC 종료

gRPC에서 클라이언트와 서버는 모두 호출의 성공에 대해 독립적이고 로컬한 결정을 내리며, 그들의 결론은 일치하지 않을 수 있습니다. 즉, 예를 들어 서버 측에서 성공적으로 완료되는 RPC("모든 응답을 보냈습니다!")가 있지만 클라이언트 측에서는 실패할 수 있습니다("응답이 마감일 이후에 도착했습니다!"). 클라이언트가 모든 요청을 보내기 전에 서버가 완료하기로 결정할 수도 있습니다.

RPC 취소

클라이언트나 서버는 언제든지 RPC를 취소할 수 있습니다. 취소하면 RPC가 즉시 종료되어 더 이상 작업이 수행되지 않습니다.

Warning

취소 전에 변경한 사항은 롤백되지 않습니다.

메타데이터

메타데이터는 키-값 쌍의 목록 형태로 된 특정 RPC 호출에 대한 정보(예: 인증 세부 정보 )입니다. 여기서 키는 문자열이고 값은 일반적으로 문자열이지만 이진 데이터일 수도 있습니다.

키는 대소문자를 구분하지 않으며 ASCII 문자, 숫자, 특수 문자 -, _, 로 구성되며 (gRPC 자체에 예약됨) .로 시작해서는 안 됩니다. grpc--bin 이진 값 키로 끝나지만 ASCII 값 키는 그렇지 않습니다.

gRPC는 사용자 정의 메타데이터를 사용하지 않으며, 이를 통해 클라이언트가 서버에 대한 호출과 관련된 정보를 제공할 수 있고 그 반대의 경우도 마찬가지입니다.

메타데이터에 대한 접근은 언어에 따라 다릅니다.

채널

gRPC 채널은 지정된 호스트와 포트에서 gRPC 서버에 대한 연결을 제공합니다. 클라이언트 스텁을 만들 때 사용됩니다. 클라이언트는 채널 인수를 지정하여 메시지 압축을 켜거나 끄는 것과 같이 gRPC의 기본 동작을 수정할 수 있습니다. 채널에는 connectedidle를 포함한 상태가 있습니다.

gRPC가 채널을 닫는 방식은 언어에 따라 다릅니다. 일부 언어는 채널 상태 쿼리도 허용합니다.

728x90
반응형

+ Recent posts