The Boxer
Google의 Protocol Buffers 본문
이번 포스팅에서는 Google에서 배포한 Protocol buffers를 사용하는 방법을 알아보겠습니다.
[Serialization(직렬화)]
Serialization : 컴퓨터에 존재하는 객체 혹은 데이터구조를 저장소에 저장하거나 다른 컴퓨터에 전송하기 위해 데이터 형태를 다른 포맷으로 변환하는 과정.
가령 컴퓨터 A 에서 B로 일반적인(메모리 공간을 차지하는) 데이터를 전송하려면 일단 byte단위로 데이터를 변환한 후 이를 통신 프로토콜을 통해 전송함. 하지만 객체나 데이터구조등 메모리 참조를 통해 접근해야 하는 데이터는 직렬화를 한 후 전송해야 함.
직렬화에는 여러 종류가 존재하며 Java 자체에서 지워하는 직렬화도 존재함.
[Protocol Buffers(protobuf)]
Protocol buffers : google에서 배포한 직렬화용 데이터 구조.
기존에는 XML파일 등으로 직렬화용 데이터 구조를 작성했지만, protobuf를 통해 더욱 유연하고 효율적이고 확장성 있는 데이터 구조를 작성할 수 있음.
Proto파일 : protobuf에서 데이터의 구조를 정의하는 파일. Proto파일을 컴파일 하면 각 언어에 해당하는 직렬화 가능한 Class가 생성됨
-> Proto파일을 작성한 후 직렬화 가능한 Class를 생성
특징
- Proto파일로 데이터 구조를 쉽게 설정할 수 있음
- 사용하는 언어에 제한받지 않고 유연하게 클래스 생성 가능
- 클래스를 직렬화 하기 때문에 다양한 데이터의 종류를 입력할 수 있음
- gRPC전송을 사용하여 더욱 빠르게 전송 가능(*다음 포스팅에서 다룰 예정)
예시
syntax = "proto3";
option java_multiple_files = true;
option java_package = "astro.com.message";
option java_outer_classname = "MessageProto";
service Transport {
rpc sendMessage(AstroMessage) returns (Return) {}
rpc sendACK(ACK) returns (Return) {}
}
message AstroMessage {
string topic = 1;
int32 index = 2;
int64 datetime = 3;
string uuid = 4;
string message = 5;
}
message Return {
enum successCode {
SuccessCodeDefault = 0;
Success = 100;
}
int32 returnCode = 1;
}
message ACK {
int32 ACKCode = 1;
}
1. Syntax
가장 먼저 사용할 syntax 버전을 명시해야 함. 현재 기준 가장 최신 버전은 proto3.
이는 파일을 proto파일로 사용할 것이라는 것을 명시.
2. 컴파일 설정
proto파일을 컴파일 할 시에 수행할 명령을 입력합니다.
option java_multiple_files은 proto파일을 여러 class로 나눠 생성할 것을 명시.
true로 입력할 경우 위에 보이는 message 구조를 각기 다른 class로 생성.
option java_package은 class가 담길 pakage를 명시.
option java_outer_classname은 생성된 메인 class의 이름을 명시.
3. service
proto파일을 생성하면 이를 보낼 service를 명시해야 함. 다른 송신 방법을 사용한다면 명시하지 않아도 되지만 필자는 google에서 제공하는 gRPC를 사용했기 때문에 service를 작성함.
4. message
class로 생성될 구조를 정의. class에 들어갈 속성을 입력할 수 있음.
속성으로 입력될 타입의 종류는 https://developers.google.com/protocol-buffers/docs/proto3 에서 확인가능.
타입의 종류마다 값이 설정되어 있는데, 이는 proto파일이 변수를 구분하기 위한 구분자. 각 class 안에 있는 변수는 모두 다른 값을 가져야 함.
*enum
proto파일은 enum 또한 설정이 가능. enum은 열거형 타입이라고도 하며 int값을 대체하기 위해서 사용.
예를들어 enum week {mon, tue, wed, thur, fri, sat, sun} 등으로 입력할 경우 mon = 0, tue = 1... 의 값을 갖게 됨. 여기서 mon = 100으로 지정할 경우 tue = 101부터 새로 시작 됨.
-> 즉, 직전 값의 + 1한 정수 값을 enum의 모든 변수로 치환할 수 있습니다.
proto파일에서는 지정된 구분자가 enum 변수의 값으로 치환됨. 또한, enum변수의 첫번째 값은 항상 0으로 입력해야 함.
[참고]
우아한 형제들(Java 직렬화) : http://woowabros.github.io/experience/2017/10/17/java-serialize.html
https://developers.google.com/protocol-buffers/docs/overview