RPC와 gRPC에 대해서

saewoohan·2025년 3월 20일

MSA

목록 보기
5/5
post-thumbnail

RPC란?

  • Remote Procedure Call의 약자로, 현재 실행 중인 프로세스의 주소 공간에서 호출하는 것이 아니라, 외부의 프로세스와 상호작용하기 위한 프로토콜이다.
    • 즉, 네트워크를 통해 다른 프로세스와 상호작용 하는 IPC의 일종이라고 볼 수 있다.
  • 네트워크로 외부의 프로세스와 상호작용하기 위한 프로토콜은 가장 대표적으로 REST API가 있다.
    • 그렇다면 REST API와의 차이점은 무엇인가?
    • Rest API는 자원을 HTTP 메소드 (GET, POST 등)으로 구분해서 요청하는 구조이며, RPC는 원격의 함수를 마치 로컬에 있는 함수처럼 호출해 결과를 가져오는 방식이다.
  • 실제 RPC자체는 1980년대부터 존재하는 기술이었고 계속 사용되었던 기술이다.
    • REST API가 익숙한 베이비 개발자 입장에서는 REST API 가 더 최근에 만들어진 개념인게 약간 놀랍기는하다.

함수 vs 프로시저

  • 함수: input에 따른 output의 발생을 목적으로 한다. 즉, return값이 필수
  • 프로시저: output에 집중하기 보다는 명령 단위가 수행하는 절차에 집중한 개념

필요성

  • 그냥 통상적으로 많이 쓰는 REST API를 사용하면 되는 것 아닌가? 왜 필요한 기술인건가?
  • 소프트웨어 개발에서는 하나의 서비스를 만들기 위해서 각 기능의 요구에 따라 다양한 언어와 프레임워크를 사용하는 경우가 많다.

  • 또한, 최근 MSA구조가 사용되면서, 하나의 서비스에서도 다양한 프로세스 간에 통신하는 것이 필요하다.
  • 서로 다른 프로세스에서 실행 중인 서버 혹은 프로그램 간에 동일한 방식으로 통신하기 위해서는 메시지 포맷이나 오류 처리 등을 각각 작성해 줘야한다.
    • RPC는 Client-Server간의 커뮤니케이션에 필요한 정보는 최대한 감추고, 일반 메소드를 호출하는 것처럼 다른 프로세스의 프로시저를 호출하는 것에 목적을 둔다.

  • 이런 복잡함을 개선하기 위해서 각기 다른 환경에서도 동일하게 적용 가능하고 단순화 할 수 있는 RPC가 유용한 것이다.

작동 원리

  • RPC는 크게 IDL (Interface Definition Language)를 이용한 방식과 이를 사용하지 않는 방식으로 분류된다.
  • IDL은 클라이언트와 서버간의 인터페이스를 정의하는 언어인데, 이를 사용하지 않는 경우 네트워크와 관련된 처리를 직접 해줘야한다는 차이가 존재한다.
  1. 클라이언트 프로세스는 서버의 함수를 호출하기 위해 사전에 IDL 로 작성된 (혹은 수동으로 정의한) 클라이언트의 Stub 에 존재하는 함수를 호출한다.
    • 이때, Stub은 서로 다른 환경의 프로세스를 호출하기 위해 정의한 추상화 객체이다.
  2. 이때, Stub은 원격 호출을 위해 함수의 매개변수를 직렬화한다, 이는 데이터를 네트워크 전송이 가능하도록 변환하는 과정이며 이를 Marshalling이라고 한다.
    • 이진 형식, JSON, 프로토콜 버퍼와 같은 포맷을 사용
  3. 이후 마샬링된 데이터는 네트워크를 통해 서버에 전송된다.
  4. 서버는 해당 데이터를 받고, 다시 서버에서 사용 가능한 형태로 복원하는데, 이를 Unmarshalling이라고 한다.
  5. 해당 언마샬링된 데이터와 함께 서버 스텁에서 서버의 함수를 호출하고, return 값이 있다면 다시 클라이언트에 전송할 수 있도록 마샬링을 수행한다.
    • 이후 마샬링된 결과를 같은 과정으로 다시 클라이언트에게 전달.

장단점

장점

  • 앞서 말했듯이 네트워크 통신의 복잡성을 추상화하여 각기다양한 환경에서도 쉽게 커뮤니케이션을 할 수 있다.
  • RPC는 JSON 포맷이 아니라, 이진 직렬화 혹은 프로토콜 버퍼 (gRPC)를 사용하는데, 이는 데이터의 크기가 줄어들어 데이터 전송 속도가 빠르다.

단점

  • 서버와 클라이언트가 사전에 정의된 인터페이스 (IDL)에 강하게 의존하기에, 변화에 따라 서버와 클라이언트 모두 대응해줘야 한다.
  • 함수처럼 호출하지만, 엄밀히 네트워크 통신을 통해 이루어지므로, 해당 과정에서 발생하는 직렬화, 역직렬화, 네트워크 등의 문제를 겪을 수 있다.

gRPC

개요

  • gRPC에서 클라이언트는 네트워크 상의 다른 서버의 메서드를 로컬 객체처럼 호출할 수 있다.
    • 다른 RPC 시스템과 마찬가지로 gRPC는 원격 호출이 가능한 서비스를 정의하고, 호출할 메서드와 매개변수, 반환 타입을 명시하는 방식으로 이루어진다.
    • 서버측에서는 이러한 인터페이스를 구현하고, gRPC 서버를 실행해서 클라이언트의 요청을 처리한다.

Protocol Buffers

  • gRPC는 Protocol Buffers를 사용해서 데이터를 직렬화한다.
    • 이전에 RPC에서 소개했던 마샬링과 언마샬링에서 사용되는 포맷이 gRPC에서는 Protocol Buffers인 것이다.
  • 먼저 proto파일에서 직렬화할 데이터의 구조를 정의하며, 각 메시지는 이름과 값 쌍으로 구성된 여러 필드로 구성된다.
message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}
  • 이렇게 데이터 구조를 정의한 후에, 프로토콜 버퍼 컴파일러 (protoc)를 사용해 proto정의에서 데이터를 접근할 수 있는 class code를 생성한다.
  • 아래 사진을 보면, 필드 번호, 필드 유형등을 1byte로 받아서 식별하고, 정해진 length만큼 읽도록 해서 단지 33 byte만 소요되는 장점을 볼 수 있다.

gRPC Service

// Greeter 서비스 정의
service Greeter {
  // 인사 전송
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// 요청 메시지에 사용자 이름을 포함
message HelloRequest {
  string name = 1;
}

// 응답 메시지에 인사 메시지 포함
message HelloReply {
  string message = 1;
}
  • gRPC 서비스 정의는 일반 proto 파일에서 정의할 수 있으며, RPC 메서드의 매개변수와 반환 타입을 프로토콜 버퍼 메시지로 지정해서 생성한다.

Service Methods

  • gRPC에는 4가지 유형의 서비스를 지원한다.
    • 양방향 통신 및 스트리밍도 가능하다는 점이 큰 장점이라고 느껴진다.
    • 이는 gRPC가 HTTP/2 기반으로 통신하기에, 동시에 데이터를 스트리밍으로 주고받을 수 있는 것이다.
  1. Unary RPC : 클라이언트가 서버에 단일 요청을 보내고 단일 응답을 받는다.
rpc SayHello(HelloRequest) returns (HelloResponse);
  1. Server streaming RPC : 클라이언트가 서버에 요청을 보내면, 서버가 여러 응답을 순차적으로 전송할 수 있다.
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
  1. Client streaming RPC : 클라이언트가 서버에 여러 요청을 전송하고, 서버가 한 번에 응답을 보낸다.
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
  1. Bidirectional streaming RPC : 클라이언트와 서버가 서로 독립적으로 메시지 스트림을 주고받을 수 있다.
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);

장단점

  • gRPC는 아래와 같이 뚜렷한 장단점을 가지고 있다.
  • 하지만 브라우저가 불필요한 분산 환경에서는 속도와 Protobuf를 사용한 처리 효율에서 굉장한 강점을 보인다.

장점

  • 네트워크 요청을 하기위해 마샬링과, 언마샬링을 하는데 이 과정에서 Protobuf를 사용하기에 JSON보다 훨씬 빠르다.
    • 이는 gRPCBenchmarks에서 뚜렷하게 차이점을 확인할 수 있다.
  • 내부적으로 HTTP/2를 기반으로 하기에, 헤더 압축 및 양방향 스트림 통신이 가능하다.

단점

  • 브라우저 환경에서 사용할 수 없다. 이는 HTTP/2와 Protobuf를 사용하기에 브라우저와 호환되지 않아 사용할 수 없다.
  • 직접 구축해보지는 않았기에, 직접 와닿지는 않지만 REST보다 구현과 구축이 더 복잡한 단점이 존재한다고 한다.

0개의 댓글