Google에서 개발한 언어에 상관없이 사용할 수 있는 고성능 RPC 프레임워크입니다.
특히 마이크로서비스 아키텍쳐에서 많이 사용됩니다.
RPC의 핵심 개념은 Stub (스텁)이라는 것입니다.
서버와 클라이언트는 서로 다른 주소 공간을 사용하므로, 함수 호출에 사용된 매개 변수를 꼭 변환해줘야 합니다.
이 변환을 담당하는게 스텁입니다.

RPC 구조 (출처 :https://middlewares.files.wordpress.com/2008/04/17.jpg)
IDL을 사용하여 호출 규약 정의합니다.
Stub Code에 명시된 함수는 원시코드의 형태로, 상세 기능은 server에서 구현됩니다.
client에서 stub 에 정의된 함수를 사용할 때,
client stub 은 RPC runtime을 통해 함수를 호출하고,
server는 수신된 procedure 호출에 대한 처리 후 결과 값을 반환합니다.
최종적으로 Cilent는 Server의 결과 값을 반환받고, 함수를 Local에 있는 것 처럼 사용할 수 있습니다.
RPC는 상당히 획기적인 방법론이었으며, 분산 환경의 등장에 따라 함께 발전해 온 오래된 기술입니다.
따라서 구현체도 CORBA, RMI 등 여러가지가 있었는데요.
이들 모두 로컬에서 제공하는 빠른 속도, 가용성 등을 분산 프로그래밍에서도 제공하고 있다고 홍보를 했지만, 정작 구현의 어려움/지원 기능의 한계 등으로 제대로 활용되지 못했습니다. 그렇게 RPC 프로젝트도 점차 뒷길로 가게되며 데이터 통신을 우리에게 익숙한 Web을 활용해보려는 시도로 이어졌고, 이 자리를 REST가 차지하게됩니다.
REST는 HTTP/1.1 기반으로 URI를 통해 모든 자원(Resource)을 명시하고 HTTP Method를 통해 처리하는 아키텍쳐 입니다.
덧붙여, 웹 데이터 전달 format으로 xml, json을 많이 사용하는데요.
HTTP/2 기반으로 동작합니다. HTTP/2의 멀티플렉싱 기능을 통해 하나의 커넥션에서 동시에 여러 요청과 응답을 처리할 수 있습니다.
Protocol Buffer(Protobuf)를 데이터 직렬화 포맷으로 사용합니다.
Protobuf는 데이터 구조를 컴팩트하게 직렬화하며, JSON보다 더 빠르고 효율적인 직렬화와 역직렬화를 제공합니다.
다양한 언어 지원
클라이언트와 서버 간의 양방향 스트리밍을 지원합니다. 따라서 실시간 데이터 전송에 유용합니다
Binary Protocol 을 사용해서 데이터 전송합니다.
- 데이터의 직렬화와 파싱이 효율적입니다.
Multiplexing : 하나의 TCP 연결에서 여러 요청과 응답을 동시에 처리할 수 있습니다.
- 네트워크 효율성을 향상시키고 요청 및 응답간의 지연속도를 줄입니다.
HPACK : 헤더 압축 알고리즘을 사용해서 요청과 응답 헤더를 압축합니다. 헤더의 중복을 줄이고 전송 데이터의 크기를 줄여 네트워크 대역폭을 절약합니다.
Server Push : 서버가 클라이언트의 요청을 예상하고 필요한 리소스를 클라이언트에게 미리 전송할 수 있습니다.
gRPC의 클라이언트와 서버간의 인터페이스를 정의하고 구현하는 역할을 합니다.
client Stub : 클라이언트에서 원격 프로시저를 호출하는데 사용되는 객체입니다. 해당 Stub으로 서버의 매서드를 로컬 메서드처럼 호출할 수 있습니다.
server Stub : 서버 측에서 클라이언트의 요청을 처리하는데 사용되는 객체입니다. 해당 stub으로 클라이언트의 요청을 수신하고, 적절한 로직을 수행하여 응답을 클라이언트에게 반환합니다.
데이터 구조를 정의하고, 이 구조에 따라 데이터를 직렬화하고 역직렬화합니다.
Protobuf는 다양한 프로그래밍 언어와 플랫폼에서 사용될 수 있는 데이터를 정의하는 방법을 제공합니다.
Protobuf는 protoc를 이용해서 .proto 파일을 기반으로 다양한 프로그래밍 언어에 맞는 소스 코드를 자동으로 생성합니다.
# proto file
syntax = "proto3";
// 메시지 정의
message Person {
int32 id = 1;
string name = 2;
string email = 3;
}
// RPC 서비스 정의
service ExampleService {
rpc GetPerson (PersonRequest) returns (Person);
}
// 요청 메시지 정의
message PersonRequest {
int32 id = 1;
}