회사에서 모듈을 개발하던 중 통신을 해야하는데 효율적인 방법을 찾다 Thrift를 사용하게 되었습니다. 처음 사용해보는데 생각보다 재미있어서 사용기를 적어봅니다.
1. Thrift란?
아래 링크는 Thrift공식 홈페이지입니다.
소개가 간략하게 되어있는데 번역하면 이런 내용인 것 같습니다.
Apache Thrift는서로 다른 언어간의 서비스를 효율적이고 원활하게 개발하기 위해 확장 가능한 software framework로 software stack과 code generation engine을 결합하였습니다. 지원 언어로는 C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, Cocoa, JavaScript, Node.js, Smalltalk, OCaml, Delphi 등을 지원합니다.
Thrift는 원래 Facebook에서 만들었고 2007년 오픈소스화, 2008년 Apache Incubator에 속해졌습니다.
통신 방식으로 RPC방식을 사용하고 있는데 간단하게 RPC통신에 대해서도 적어보았습니다.
1-1. RPC통신이란?
우선 위키백과를 한번 살펴보겠습니다.
원격 프로시저 호출(영어: remote procedure call, 리모트 프로시저 콜, RPC)은 별도의 원격 제어를 위한 코딩 없이 다른 주소 공간에서 함수나 프로시저를 실행할 수 있게하는 프로세스 간 통신 기술이다. 다시 말해, 원격 프로시저 호출을 이용하면 프로그래머는 함수가 실행 프로그램에 로컬 위치에 있든 원격 위치에 있든 동일한 코드를 이용할 수 있다.
사용하는 입장에서 저 글을 요약해보면 서버에 있는 함수나 프로시저를 쉽게 호출해서 사용할 수 있는 것 같습니다.
2. Thrift의 구조
Thrift는 코드가 자동으로 생성되는 부분들이 있어 깊숙한 부분까지 신경을 쓰지 않아도 됩니다.
2-1. 서비스 정의(IDL)
Thrift를 사용하기 위해 서비스를 정의해야하는데 이 파일을 IDL(Interface Definition Language)을 이용해 만듭니다.
파일의 확장자는 .thrift이고 tutorial.thrift파일을 가져와서 주석을 수정해서 설명을 달고 살펴보겠습니다.
// Thrift IDL의 데이터 타입입니다.
/**
* The first thing to know about are types. The available types in Thrift are:
*
* bool Boolean, one byte
* i8 (byte) Signed 8-bit integer
* i16 Signed 16-bit integer
* i32 Signed 32-bit integer
* i64 Signed 64-bit integer
* double 64-bit floating point value
* string String
* binary Blob (byte array)
* map<t1,t2> Map from one type to another
* list<t1> Ordered list of one type
* set<t1> Set of unique elements of one type
*
* Did you also notice that Thrift supports C style comments?
*/
// thrift는 다른 thrift파일을 include하여 사용할 수 있습니다.
include "shared.thrift"
/**
* Thrift files can namespace, package, or prefix their output in various
* target languages.
*/
// 어떤 언어로 내보낼지 namespace를 설정합니다.
namespace cl tutorial
namespace cpp tutorial
namespace d tutorial
namespace dart tutorial
namespace java tutorial
namespace php tutorial
namespace perl tutorial
namespace haxe tutorial
namespace netstd tutorial
// thrift IDL에서는 C스타일로 다시 데이터 타입을 Wrapping해서 사용할 수 있습니다.
typedef i32 MyInteger
// thrift IDL에서는 const를 사용해 상수를 정의한 후 사용할 수 있습니다.
const i32 INT32CONSTANT = 9853
const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}
// enum도 사용할 수 있습니다.
enum Operation {
ADD = 1,
SUBTRACT = 2,
MULTIPLY = 3,
DIVIDE = 4
}
// IDL내에서 구조체를 정의할 수 있습니다. 구조체가 없는 언어에서는 class로 정의되어 생성됩니다.
struct Work {
1: i32 num1 = 0,
2: i32 num2,
3: Operation op,
4: optional string comment,
}
// exception도 정의할 수 있습니다.
exception InvalidOperation {
1: i32 whatOp,
2: string why
}
// 서비스를 정의하는 부분입니다. 다른 서비스를 상속하여 사용할 수 있습니다.
service Calculator extends shared.SharedService {
// 서비스내 함수를 정의합니다.
// [return type] [function name(params)] [options : throws] 형식으로 적으시면 됩니다.
void ping(),
i32 add(1:i32 num1, 2:i32 num2),
i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),
}
다음 글에서는 Thrift의 실제 사용 방법에 대해 적어보겠습니다.