애플리케이션 서버 :: 시스템의 주요 기능을 실행하고 결과를 화면 계층으로 전다달하는 기능을 수행하는 서버
| 애플리케이션서버 | 웹서버 | 웹 애플리케이션 서버 |
원격 프로시저 호출(Remote procedure call, RPC)은 컴퓨터 프로그램이 다른 주소 공간에서 원격 제어를 위한 프로그래머의 세세한 코딩 없이 함수나 프로시저의 실행을 허용하는 기술이다.
인터페이스 정의 언어(Interface Description Language 또는 Interface Definition Language, IDL)는 소프트웨어 컴포넌트의 인터페이스를 묘사하기 위한 명세 언어이다. IDL은 어느 한 언어에 국한되지 않는 언어중립적인 방법으로 인터페이스를 표현함으로써, 같은 언어를 사용하지 않는 소프트웨어 컴포넌트 사이의 통신을 가능하게 한다. 예를 들면, C++을 사용하여 작성한 컴포넌트와 자바를 사용한 컴포넌트 사이에서 국한되지 않고, 인터페이스를 묘사하는 개념이다.
thrift server를 만들기 전에 먼저 IDL (Interface Defition Language)을 통해서 어떤 메소드를 다른 프로그래밍언어간에 서로 어떤 방식으로 통신할 지를 정해주어야 합니다.
(여기서 thrift에서 생성되는 언어별 네임스페이도 같이 정해줄 수 있습니다.)
namespace java com.example.thrift
namespace py thrift
위와 같은 코드는 thrift가 생성하는 파일이 자바의 경우 com.example.thrift 로 패키징 되고,
파이썬의 경우 thrift로 패키지가 되어 코드가 생성됩니다.
문자열은 binary, 일반적인 integer는 i32로 정의하였습니다. 이런 형식으로 데이타 타입을 정의하여 thrift로 생성하면 TNode.java가 생성되어 bean entity로 사용 가능합니다.
struct TNode {
1:binary value,
2:i32 count,
3:i64 timestamp
}
예외도 처리 가능합니다.
exception IOError {
1:binary message
}
메소드를 사용하기 위해서는 서비스 등록을 해야합니다. 이 IDL은 두 개의 메소드를 등록해 줍니다.
service Example {
void write(
1:binary data
) throws (1:IOError io)
TNode get(
1:i32 position
) throws (1:IOError io)
}
자바 표현은 다음과 같습니다.
void write(String data) throws IOError;
TNode get(int position) throws IOError;
thirft --gen java example_idl.thrift
물론 thrift를 설치한 후에 위와 같이 실행을 합니다. example_idl.thrift라는 파일은 1에서 언급된 내용들이 있는 파일이며 IDL에 따라 com.example.thrift 밑에 아래와 같은 파일들이 생깁니다.
Example.java (서비스에 등록한 이름을 가지고 생성된 메소드들의 interface를 제공하는 파일)
TNode.java (struct로 정의한 내용이 생성된 파일)
IOError.java (erorr를 정의한 내용이 생성된 파일)
여기서 생성된 모든 파일은 thrift server를 만들 때에 모두 import 해야 합니다.
thrift --gen php example_idl.thrift
java와 마찬가지로 비슷한 php 코드들을 생성해 줍니다.
여기서 생성된 코드들은 후에 client를 작성할 때에 모두 include 해서 사용합니다.
public static void main(String[] args) {
// ExampleHandler는 생성된 Example.java를 상속해서 실제로 IDL에 정의된 함수를 구현한 파일
ExampleHandler handler = new ExampleHandler();
// Example.java 안에 생성된 클래스를 이용해서 handler 등록
Example.Processor processor = new Example.Processor(handler);
TServerTransport serverTransport = new TServerSocket(9090);
// 서버의 종류는 TSimpleServer 이외에도 TNonblockingServer, TBoundedThreadPoolServer ...
TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));
server.serve();
}
실행은 그냥 자바 어플리케이션 실행하듯이 하면 되며, thrift에 의해서 생성된 파일들 모두 import 합니다.
이제 4에서 언급된 ExampleHandler.java를 구현해야 합니다.
public class ExampleHandler implements Example.Iface {
private ArrayList<TNode> buffer = new ArrayList<TNode>();
void write(String data) throws IOError {
TNode node = new TNode(data, 13, System.currentTimeMillis());
buffer.add(node);
}
TNode get(int position) throws IOErro {
return buffer.get(position);
}
}
예시를 위한 것이기 때문에 실제로 구현할 때에는 좀 더 추가해야 할 코드들이 있겠지만, 기본적으로 이렇게 해주면, 외부에서 이 메소드를 사용할 수 있습니다.
php client를 돌릴 서버에 thrift source code의 lib/php/src 디렉토리를 복사합니다.
여기서는 /home/www/php/src 로 복사를 했다고 가정 합시다.
thrift에 의해서 생성된 파일들을 위의 /home/www/php/src 밑에 packages라는 이름으로 복사를 해 둡니다. (여기에는 Example.php 및 기타 파일이 존재합니다.)
$GLOBALS['THRIFT_ROOT'] = '/home/www/php/src';
require_once( $GLOBALS['THRIFT_ROOT'].'/Thrift.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php' );
require_once( $GLOBALS['THRIFT_ROOT'].'/packages/thrift/Example.php' );
$socket = new TSocket(THRIFT_SERVER_IP, 9090 );
$socket->setSendTimeout( 10000 ); // Ten seconds
$socket->setRecvTimeout( 20000 ); // Twenty seconds
$transport = new TBufferedTransport( $socket );
$protocol = new TBinaryProtocol( $transport );
$client = new HbaseClient( $protocol );
$transport->open();
여기서 생성된 $client를 이용해서 thrift server에서 돌아가고 있는 메소드를 호출할 수 있습니다.
$client->write("Hello World!");
$result = $client->get(5);
$result는 php의 array 형식일 것 입니다만 확인이 필요합니다.
위와 같은 방법으로 원하는 메소드들을 다른 프로그래밍 언어에서 호출할 수 있습니다.
thrift 문서보다는 HBase 소스 코드를 다운로드 받아서 그 안에 있는 thrift server부분의 코드를 살펴보면 이해에 훨씬 도움이 될 것 이며, 다른 언어로 thrift server를 만들고 싶으시다면 thrift 소스 코드를 받으신 후에 tutorial 디렉토리에 있는 각 언어별 예제를 보시면 됩니다.

