gRPC

mohadang·2023년 9월 12일
0

Road to Backend

목록 보기
8/21
post-thumbnail

RPC

Remote Procedure Call : 네트워크로 연결된 서버 상의 프로시저(함수, 메서드, ...)를 원격으로 호출하는 기능.

RPC를 사용하면 클라이언트는 마치 로컬에서 함수를 호출 하듯 서버의 프로시저를 호출할 수 있다.

Stub

RPC의 구성품. 마샬링 처리 수행.

Client Stub

  • 함수 호출에 사용된 파라미터 변환.
  • 함수 실행 후 서버에서 전달 된 결과의 변환.
  • RPC Runtime을 통해 함수 호출.

Server Stub

  • 클라이언트가 전달한 매개 변수의 역변환(언마샬링).
  • 함수 실행 결과 변환.
  • 수신된 Procedure 호출에 대한 처리 후 결과 값을 반환.

IDL

Interface Definition Language : 호출 규약 정의 언어.

RPC는 IDL을 사용하여 클라이언트와 서버가 어떻게 호출, 값 전달 할지 규약을 정의한다. IDL 언어를 정의한 후 컴파일 하면 Stub Code가 자동으로 생성된다. Stub Code에 명시된 함수는 원시 코드의 형태로, 상세 기능은 server에서 구현된다. 만들어진 Stub 코드는 클라이언트/서버에서 사용할 수 있다.

RPC 장점

  • 원격 서버의 프로시저를 호출하는 방식으로 사용법이 편리.
  • IDL 사용하면 여러 언어로 코드를 자동 생성하기에 확장성이 좋다.

RPC vs REST

REST

  • HTTP/1.1 기반
  • URI를 통해 모든 자원(Resource)을 명시. 자원 그 자체를 표현하기에 직관적.
  • HTTP Method를 통해 처리하는 아키텍쳐. HTTP를 그대로 계승하였기에 별도 작업 없이도 쉽게 사용할 수 있어 매우 보편화됨.
  • REST는 일종의 스타일이지 표준이 아니기 때문에 parameter와 응답 값이 명시적이지 않음.
    • 하지만 어느정도 상식 수준의 규칙이 있어 대부분 이 규칙을 지킨다.
  • HTTP 메소드의 형태가 제한적이기 때문에 세부 기능 구현에는 제약.
  • 웹 데이터 전달 format으로 xml, json을 많이 사용.
    • XML
      • html과 같이 tag 기반.
      • 미리 정의된 태그가 없어(no pre-defined tags) 높은 확장성을 인정 받아 이기종간 데이터 전송의 표준이었으나, 다소 복잡하고 비효율적인 데이터 구조탓에 속도가 느리다는 단점.
    • JSON
      • Key-Value 구조 기반으로 XML 효츌 문제 해결.
      • 제공되는 자료형의 한계로 파싱 후 추가 형변환이 필요한 경우가 많아짐.
      • 두 타입 모두 string 기반이라 사람이 읽기 편하다는 장점은 있으나, 바꿔 말하면 데이터 전송 및 처리를 위해선 별도의 Serialization이 필요하기에 성능 면에서 비효츌적.

gRPC

google Remote Procedure Call : google 사에서 개발한 오픈소스 RPC(Remote Procedure Call) 프레임워크.

이전까지는 RPC 기능은 지원하지 않고, 메세지(JSON 등)을 Serialize할 수 있는 프레임워크인 PB(Protocol Buffer, 프로토콜 버퍼)만을 제공

REST와 달리 HTTP/2 사용 및 프로토콜 버퍼로 데이터를 전달. Proto File만 배포하면 환경과 프로그램 언어에 구애받지 않고 서로 간의 데이터 통신이 가능.

HTTP/2

HTTP/1.1

  • 클라이언트의 요청이 올때만 서버가 응답.(핑퐁, 동기적인 방식)
  • 매 요청마다 connection 생성(부하)
  • cookie등 많은 메타 정보들을 저장하는 무거운 header가 요청마다 중복 전달.

HTTP/2

  • 한 connection으로 동시에여러 메시지를 전달.
  • header를 압축하여 중복 제거 후 전달.
  • 클라이언트 요청 없이도 서버가 리소스를 전달할 수 있기에 클라이언트 요청 최소화 가능.(양방향)

ProtoBuf(Protocol Buffer, 프로토콜 버퍼)

Protocol Buffer는 google 사에서 개발한 구조화된 데이터를 직렬화(Serialization : Ex - json, xml, ...)하는 기법.

Ex) Json vs ProtoBuf

Json : 82 byte 소요(key, value, '{', ...)

  • 텍스트 기반 serialize

ProtoBuf : 33 byte(필드 번호(1), 필드 유형(1), ...)

  • 바이너리 기반 serialize

대신 Json 처럼 Serialize 결과와 선언이 하나가 아니고 별도의 proto 파일이 필요 하다는점. proto 파일 자체를 전달할 수 없는 점은 개발시 조금더 번거롭다는 의견이 있을 수 있다.

서비스 정의

클라이언트와 서버간의 통신 규약을 proto 파일에 정의한다.

*.proto


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

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}

gRPC는 클라이언트와 서버사이드 코드를 생성하는 프로토콜 버퍼 컴파일러 플러그인들을 제공한다.

proto 파일만 잘 정의하면 클라이언트와 서버는 플러그인을 사용하여 각자의 언어에 맞는 API 소스 파일을 생성하고 이 소스 파일에 정의된 API들을 사용하여 통신을 할 수 있다.

gRPC를 사용하여 통신할때 클라이언트/서버의 역할은 다음과 같드

  • 클라이언트 : 서버 사이드 소스 코드 참조하여 API 호출.
  • 서버 : 서버 사이드 API 내부 구현.

통신 방식

다음과 같이 4가지 종류가 있는데 Unary, streaming 이라는 단어의 의미만 알면 해석이 가능하다.

  • Unary RPC
  • Server streaming RPC
  • Client streaming RPC
  • Bidirectional streaming RPC

Unary : 단항이라는 의미이다.
streaming : streaming은 스트림을 전달 한다는 의미이다. 메시지 순서는 gRPC에서 보장한다.
Bidirectional : 양쪽이라는 의미이다.

Unary RPC

  • rpc SayHello(HelloRequest) returns (HelloResponse);
  • 1 Request + 1 Reply.
  • 동기적으로 데이터를 주고 받음.
  • 일반적인 REST API와 같은 사용 방식이다.

Server streaming RPC

  • rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
  • 1 Request + N Reply.
  • 동기적으로 데이터를 주고 받음.

Client streaming RPC

  • rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
  • N Request + 1 Reply.
  • 동기적으로 데이터를 주고 받음.

Bidirectional streaming RPC

  • rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
  • N Request + N Reply.
  • stream HelloRequest, stream HelloResponse 두 스트림이 독립적으로 운영되기에 어떤 순서로든 메시지릴 읽건나 쓸 수 있다
    • Ex) 서버는 클라이언트의 모든 메시지를 수신한 다음 응답 메시지 전달 가능(Client streaming RPC)
    • Ex) 핑퐁 방식(Unary RPC)

Deadlines/Timeouts

gRPC는 클라이언트의 대기 시간을 설정할 수 있다. 대기 시간을 만료하게 되면 클라이언트에서 해당 RPC에 대해 DEADLINE_EXCEEDED 에러 발생한다. 서버 사이드에서는 서버가 해당 RPC의 남은 만료 시간 확인 가능.

만료 시간은 언어마다 다르다. 어떤 언어에서는 timeouts이라는 조건을 사용하고 어떤 언어에서는 deadline이라는 조건을 이용한다.

RPC 종료

클라이언트와 서버의 처리 결과가 다를 수 있다(Ex: 서버는 성공, 클라이언트는 실패).
클라이언트가 모든 요청을 보내기 전에 서버는 종료할 수 있다.

메타 데이터

RPC 호출에 대한 정보이며 key-value 형태로 이루어져 있다.

메타 데이터는 gRPC가 생성한 API를 통해서 전달되지 않고 gRPC 백그라운드 단에서 전달 된다. 메타 데이터 접근은 사용 언어에 따라 가능 할 수 있다.

채널

host, port로 채널 연결. 채널 연결시 클라이언트는 스텁 생성.

클라이언트는 메시지 압축을 키거나 끄는 등의 gPRC의 기본 행동을 제어하기 위해 채널에 어떤 인자들을 명시 가능.

채널은 상태를 connected와 idle 상태를 가진다.

gPRC가 닫힌 채널을 다루는 방법은 사용 언어에 따라 처리가 다르다. 어떤 언어들은 채널 상태를 질의하는 것을 허용한다.

링크

profile
mohadang

0개의 댓글