RPC

3 분 소요

RPC (Remote Procedure Call)

RPC는 서버-클라이언트 구조 애플리케이션에서 원격에 있는 프로시저를 실행할 수 있게 하는 통신기술로 개발자는 애플리케이션이 로컬인지 원격인지에 관계없이 프로 시저를 호출함으로써 하나의 시스템 처럼 동작할 수 있는 기술이다. RPC 는 LPC(Local Procedure Call) 의 확장 개념으로 기술적으로는 프로토콜이 아니며 단지 서버-클라이언트와 같은 분산 시스템을 구성하는 일반적인 메커니즘으로 봐야한다. RPC 프로토콜은 TCP와 같은 표준 프로토콜이 아니며 RPC 가 사용되는 기능에 따라 모두 다르게 동작한다.
즉, RPC 프로토콜은 표준이 없기 때문에 데이터 통신을 위한 추상화된 프르토콜로써 실제 데이터 전송을 위해서 TCP or UDP 를 사용하여 통신한다. 여러 대의 컴퓨터에 프로시져를 분산하고, 결과를 취합하는 방식으로 분산 시스템에서 사용가능하다.
RPC 는 동기 서버, 비동기 서버, 스트리밍 서버에 모두 사용된다. 특정 프로토콜을 이용한 기술적인 개념이 아닌 원격 프로시저를 호출할 수 있다는 키워드에 집중하 면 될 듯 하다.

RPC 동작방식

RPC 는 서버/클라이언트 모두 3개의 layer 로 나눌수 있다.

  • Caller/Callee: 클라이언트/서버 비지니스 로직을 작성하는 Layer
  • (Client/Server) Stub: parameter 를 marshelling 하여 message 로 변환하거나 message 를 unmarshelling 하여 parameter 로 변환하는 작업을 수행하는 Layer
  • RPC Protocol: RPC Runtime 이라고도 불리는 RPC Protocol 은 RPC 메커니즘의 기초가 되는 네트워크 통신을 처리하는 라이브러리로 RPC 호출 과정에서 클라이언트/서버 런타임 시스템 코드를 바인딩하고 적절한 프로토콜을 통해 통신을 수행하는 Layer
    • 통신에 대한 오류처리도 담당

No Image
출처: 네트워크 ebook A System Approach RPC

  1. Caller 는 클라이언트 스텁에 매개변수를 갖고 호출
  2. 클라이언트 스텁은 변수를 marshalling 하여 요청 메시지로 변환하고 RPC 프로토콜을 호출
  3. RPC 프로토콜은 요청 메시지를 서버 시스템으로 전송
  4. 서버의 RPC 프로토콜은 서버 스텁에 요청 메시지를 전달
  5. 서버 스텁은 요청 메시지를 unmarshalling 하여 변수로 변환하고 Callee 에 전달
  6. Callee 는 요청에 대한 처리를 수행하고 응답 값을 서버 스텁으로 리턴
  7. 서버 스텁은 응답 값을 marshalling 하여 응답 메시지를 RPC 프로토콜을 통해 클라이언트로 반환
  8. 클라이언트 스텁은 응답 메시지를 unmarshalling 하여 응답 값을 Caller 로 반환

marshalling / unmarshalling - 서버-클라이언트 환경의 차이

RPC 는 서버-클라이언트 환경에서 실행되기 때문에 서버와 클라이언트 환경에 종속적이다. 즉, 네트워크 상에 전송될 데이터의 형식과 서버, 클라이언트에서 처리할 데이터의 형식을 미리 정의해야 한다. 서버와 클라이언트는 서로 다른 시스템일 수 있는데 이런 경우 데이터 포맷도 달라질 수 있는 문제가 있기 때문이다.
대표적인 예로 Unix 시스템의 RISC 프로세서 계열 에서 사용하 는 Big Endian 과 인텔 계열 프로세서에서 주로 사용하되는 Little Endian 이다. Little Endian 은 메모리 시작 주소가 하위 바이트부터 기록되는데, Big Endian 은 시 작 주소가 상위 바이트부터 기록된다.

  • marshalling : marshalling 은 데이터를 네트워크 상에 전송할 형식으로 변환하는 작업을 말하며 java serialize 가 대표적인 예라고 할 수 있다
  • unmarshalling : unmarshalling 은 네트워크에서 받은 데이터를 다시 어플리케이션에서 사용할 데이터 형식으로 변환하는 작업으로 java deserialize 가 대표적인 예다

Binding - RPC 에서는 클라이언트와 서버는 어떻게 연결할까?

클라이언트가 서버에 프로시저를 호출하기 위해서는 요청을 보낼 서버의 주소와 서버에서 동작 중인 프로세스를 식별해야 한다. 일반적으로 서버 내부에는 여러 프로 세스가 동작하는데, RPC 서버 프로시저를 식별하기 위해서 PORT 번호를 이용할 수 있다. 클라이언트에서 서버의 주소를 찾는 방법은 서버의 주소를 어떻게 지정하는지에 따라 static binding, dynamic binding 으로 나눌 수 있다.

  • static binding 서버 주소를 hard coding 하는 방법
    단순하고 효율적이지만 유연하지 않음
    서버의 주소 변경시 마다 클라이언트 스텁을 매번 재컴파일 해야하는 문제
  • dynamic binding 주소 변경에 매우 유연함
    네트워크 네임 서버 필요
    여러 서버로 구성된 경우 추가적인 load balancing 필요

No Image
출처: slideshare Distributed Operating Systems

RPC 는 왜 사용할까 ?

우리는 보편적으로 REST 를 이용해서 서버와 클라이언트 통신을 수행하고 있다.

  • 사실 필자도 REST 만을 이용해서 개발을 하다가 이직을 하면서 RPC 로 구성된 어플리케이션을 개발하면서 RPC 에 대해서 찾아보게 되었다 해당 내용은 RPC 구현체 중 하나인 Aphache Thrift 를 비교한 글에서 찾을 수 있었는데

No Image

위 그림에서는 REST 를 이용한 HTTP 통신은 일반적인 웹 환경에서는 적합하지만 성능이슈가 있다는 것을 지적하고 있다.
예를들어 사내 서비스를 개발할 때, 통신 성능이 중요하다면 RPC 를 선택하는 것도 좋은 방법이라고 주장한다.

  • 이렇게 RPC 가 REST 비해 성능이 좋은 이유는 apache thrift 가 내부적으로 빠른 binary serailize 를 구현하고 있기 때문이라고 함

결론

실제로 구글도 내부 서비스에서 프로토콜 버퍼 를 사용하고 있는데, 프로토콜 버퍼도 RPC 기술 중 하나이다. 사실 위에서 설명한 apache thrift 는 업데이트가 거의 중단된 서비스 인데 비해 프로토콜 버퍼는 지속적으로 업데이트 되고 있다.
이번 기회에 서버-클라이언트 간 통신을 위해서 REST vs RPC 를 잘 비교해서 사용해보는 것이 좋겠다는 생각을 하게 됨

Reference