Protobuf(Protocol Buffers)와 RPC
서버개발

Protobuf(Protocol Buffers)와 RPC

들어가면서

게임에서는 문자열을 모두 원본 형태로 보내는 JSON 방식이 아닌 더욱 적은 대역폭으로 전송을 하는 Protobuf를 사용하기도 한다. 이를 실무에서 사용하기 전에 공부해보고자 Protobuf와 RPC에 대한 글을 정리하였다.

 

 


 

RPC 통신

 

  • RPC 통신이란
    • Remote Procedure Call(원격 프로시저 호출)의 준말로, 별도의 원격제어 코드 없이
      다른 주소 공간에서 함수/프로시저를 실행하도록 하는 프로세스 간 통신 기술(어디든 동일 호출)
      • 함수
        • input에 따른 output의 발생
        • return값을 필요로 하며, 간단한 계산 및 수치 등을 도출할 때 사용
      • 프로시저
        • output 값에 집중보단, 명령 단위 수행절차에 집중
        • return은 없을 수도 있고, 서버단에서 함수보다 큰 실행, 프로세싱 시 사용
    • 프로세스는 기본적으로 자신의 주소공간 안에 존재하는 함수만 호출하여 실행
    • RPC는 네트워크를 통한 메시징을 수행하여 서로 다른 네트워크에서의 프로세스에서도 호출 가능
  • RPC의 목표
    • Client-Server간의 커뮤니케이션에 필요한 상세정보를 최대한 감춘다
    • Client-Server는 각각 일반 메서드를 호출하는 것처럼 원격지의 프로시저 호출 가능
  • RPC의 동작 방식
    • IDL을 사용하여 서버의 호출 규약 정의
      • 함수명, 인자, 반환값에 대한 데이터 타입이 저장된 IDL 파일을 rpcgen 컴파일러를 이용하여 Stub 코드를 자동으로 생성
      • IDL
        • Interface Defination Language의 준말로 서버의 호출 규약을 정의
        • 인터페이스 정의 언어로 언어 중립적인 방법으로 인터페이스 표현, 구현 언어가 아닌 정의 언어로 구현 언어로의 매핑을 지원
    • Stub은 원시 소스코드(C, Java) 형태로 만들어지므로, Client-Server 프로그램에 각각 포함하여 빌드
    • 서버에서는 클라이언트 Stub에 정의된 함수를 호출
    • Stub 코드는 데이터 타입을 XDR 형식으로 변환
      • XDR
        • External Data Representation의 준말로 기본 데이터 타입(정수형, 부동 소수점 등)에 대한 메모리 저장 방식(Little, Big-Endian)이 CPU 아키텍처 별로 상이하여바이트 전송 순서 보장을 위해 변경
    • 서버는 수신된 함수/프로시저 호출에 대한 처리를 서버 Stub을 통해 처리 후, 결과값을 XDR 변환하여 Return
    • 클라이언트 프로그램은 서버가 Return한 결과 값을 전송 받음
  • RPC의 장점
    • 고유 프로세스 개발에 집중 가능
    • 프로세스 간 통신 기능을 비교적 쉽게 구현하고 정교한 제어 가능
  • RPC의 단점
    • 호출 실행과 반환 시간이 보장되지 않음
      • 네트워크 구간을 통해 RPC 통신을 하는 경우 네트워크가 끊겼을 때 보장해주지 않음
    • 보안이 보장되지 않음
  • RPC의 대표적인 구현체
    • 구글의 ProtocolBuffer(protobuf)
    • 페이스북의 Thrift
    • 트위터의 Finalge

 

Protocol Buffers란

  • 구조화된 데이터 직렬화를 통해 언어, 플랫폼 중립적인 패킷을 전송할 수 있으며, 데이터를 바이너리화하여 압축하기 때문에 JSON/XML보다 적은 대역폭으로 송수신 가능
  • JSON과의 차이
    • JSON
      • 사람이 읽는 일반 텍스트로 전송하여 대역폭을 상대적으로 크게 가져가며, 두 언어 모두 쉽게 읽을 수 있어 js/html 기반 웹에서 사용하기에 더 수월
      • 사람이 읽을 수 있어 더 간편하며, 디버깅 용이
    • protobuf
      • 바이너리화되기 때문에 적은 대역폭에서도 사용할 수 있으며, 적게나마 암호화되는 효과를 볼 수 있음
      • 응용 프로그램 간 RPC통신 가능
      • 데이터 구조 변경 시 이전 버전과 호환 보장
  • 문법
    • Syntax
      • 버전을 정하는 것
      • proto2, proto3가 존재하며 default는 proto2
    • Field Types
      • double, float : 실수
      • int32, int64 : 음수에 비효율적
      • uint32, uint64 : unsigned int 같은 느낌일까요
      • sint32, sint64 : 부호있는 정수
      • fixed32, fixed64 : 항상 4, 8바이트. 값이 2^28, 2^56보다 크면 효율적
      • sfixed32, sfixed64 : 항상 4, 8바이트
      • bool : 부울
      • string : UTF-8 혹은 7bit ASCII 이여야 함
      • bytes : 임의의 바이트 배열 사용가능
    • Field Rules
      • 필드 타입 앞 선언 시 생기는 조건
        message GetUserInfo{            
            required string uid = 1;     
            optional string nickname = 2;
            repeated string address = 3; 
        }                               
      • 종류
        • required : 이 필드를 반드시 1개 가진다(반드시 필요한 필드)
        • optional : 이 필드는 가지지 않거나 1개 가진다
        • repeated : 이 필드를 0개 이상 가진다(배열처럼 사용 가능)
      • proto3에서는 required, optional → deprecate로 변경
    • Tag
      • 각 변수의 숫자는 초기화가 아닌 바이너리 형식 필드를 구분하기 위한 태그
      • 0은 사용할 수 없다
      • 15번 이전까진 1바이트 인코딩, 15번 이후로는 2바이트 인코딩
      • 19000~19999는 예약된 태그여서 사용할 수 없다
      • 태그 최대치는 2^29이다
      • string uid = 1; // 여기서 1에 해당하는 부분이 Tag이다.
    • Reserved Field
      • 기존 사용하던 필드를 중간에 제거 시, 다시 해당 필드를 재사용하게 되면 일관성 & 호환성 장애를 초래한다
      • 그래서 reserved field를 사용하여 사용하지 못하게끔 한다
        message GetUserInfo{                                 
            reserved 2;                                       
            required string uid = 1;                          
            // optional string nickname = 2; // 사용하지 않게됨
            repeated string address = 3;                      
        }                                                   
    • Style guide
      • Message 명은 파스칼케이스를 사용한다(첫 문자도 대문자인 카멜 케이스)
      • 필드명은 스네이크 케이스로 작성한다

 

 

 

 

 

 

참고 블로그

 

Protobuf 문법

목차 Syntax Field types Field Rules Tag Reserved Field service(rpc) style guide Syntax syntax = "proto3"; //proto3 버전 문법 사용 'syntax'는 버전을 정하는 구문이며 'proto2'와 'proto3'가 있다. 해당 내용이 없으면 'proto2'가 de

leo-history.tistory.com