본문 바로가기

코드 이야기

Thrift Server를 이용하여 PHP로 자바 어플리케이션 사용하기


1. thrift IDL 만들기

thrift server를 만들기 전에 먼저 IDL (Interface Defition Language)을 통해서 어떤 메소드를 서로 어떤 방식으로 통신할 지를 정해주어야 한다.

여기서 thrift에서 생성되는 언어별 네임스페이도 같이 정해줄 수 있다.

namespace
java com.example.thrift
namespace py thrift

위와 같은 코드는 thrift가 생성하는 파일이 자바의 경우 com.example.thrift 로 패키징 되고, 파이썬의 경우 thrift로 패키지가 되어 코드가 생성된다.

문자열은 binary, 일반적인 integer는 i32로 정의한다.

struct TNode {
 1:binary value,
 2:i32 count,
 3:i64 timestamp
}

 위와 같은 형식으로 데이타 타입을 정의하여 thrift로 생성하면 TNode.java가 생성되어 bean entity로 사용 가능하다.

exception IOError {
 1:binary message
}

위와 같이 예외도 처리 가능하다. 

메소드를 사용하기 위해서는 서비스 등록을 해야한다.

service Example {
   void write(
     1:binary data
    ) throws (1:IOError io)

   TNode get(
      1:i32 position
     ) throws (1:IOError io)
}

위의 IDL은 두 개의 메소드를 등록해 주는데, 자바로 표현하면 다음과 같다.
 void write(String data) throws IOError;
 TNode get(int position) throws IOError;

 
2.  자바 코드 생성하기

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 해야 한다.
 

3. php 코드 생성하기

 thrift --gen php example_idl.thrift

 java와 마찬가지로 비슷한 php 코드들을 생성해 준다.
 여기서 생성된 코드들은 후에 client를 작성할 때에 모두 include 해서 사용한다.


4. thrift server 코드 작성

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();
}

이 외에도 서버는 다양하게 있어서 API를 참조해서 설정하면 됩니다.

실행은 그냥 자바 어플리케이션 실행하듯이 하면 됩니다.
당연히 thrift에 의해서 생성된 파일들 모두 import 합니다.


5. 실제 동작 자바 함수 구현 

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);
     }
}

예시를 위한 것이기 때문에 실제로 구현할 때에는 좀 더 추가해야 할 코드들이 있겠지만, 이렇게 해주면, 외부에서 이 메소드를 사용할 수 있습니다.


6. php client 코드 작성 


 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 형식일 것입니다. (확인 필요)


 위와 같은 방법으로 원하는 메소드들을 다른 프로그래밍 언어에서 호출할 수 있습니다. 


7. 다른 언어에서의 사용

만약 ruby로 thrift server에 접속하고 싶다면, php와 동일하게 파일을 생성하고 ruby에서 사용하면 됩니다. 



거의 이대로 따라하시면 어렵지 않게 하실 수 있을 것입니다.
 thrift 문서보다는 HBase 소스 코드를 다운로드 받아서 그 안에 있는 thrift server부분의 코드를 살펴보시며 이해에 훨씬 도움이 되실 것입니다.

 다른 언어로 thrift server를 만들고 싶으시다면 thrift 소스 코드를 받으신 후에 tutorial 디렉토리에 있는 각 언어별 예제를 보시면 됩니다.



[참고]

1. http://wiki.apache.org/thrift/ThriftIDL 
2. Apache HBase 소스 코드
3. Thrift 소스 코드