3장 경량 애플리케이션 서버

애플리케이션 서버 :: 시스템의 주요 기능을 실행하고 결과를 화면 계층으로 전다달하는 기능을 수행하는 서버

애플리케이션서버웹서버웹 애플리케이션 서버
  • 이상적 애플리케이션 서버에 대한 요구사항

RPC(Remote Procedure Call)

원격 프로시저 호출(Remote procedure call, RPC)은 컴퓨터 프로그램이 다른 주소 공간에서 원격 제어를 위한 프로그래머의 세세한 코딩 없이 함수나 프로시저의 실행을 허용하는 기술이다.

  • RMI
  • DCOM
  • CORBA
  • XML-RPC
  • protocol buffers
  • Thrift
  • Etch

IDL

인터페이스 정의 언어(Interface Description Language 또는 Interface Definition Language, IDL)는 소프트웨어 컴포넌트의 인터페이스를 묘사하기 위한 명세 언어이다. IDL은 어느 한 언어에 국한되지 않는 언어중립적인 방법으로 인터페이스를 표현함으로써, 같은 언어를 사용하지 않는 소프트웨어 컴포넌트 사이의 통신을 가능하게 한다. 예를 들면, C++을 사용하여 작성한 컴포넌트와 자바를 사용한 컴포넌트 사이에서 국한되지 않고, 인터페이스를 묘사하는 개념이다.

  • Microsoft IDL (DCOM)
  • OMG IDL (CORBA)
  • Web IDL
  • Protobol Buffers
  • Thrift

Thrift

  • 서로 다른 프로그래밍 언어간에 통신할 수 있는 RPC 클라이언트와 서버를 쉽게 만들 수 있게 도와 주는 프레임웍
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로 정의하였습니다. 이런 형식으로 데이타 타입을 정의하여 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;

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

실행은 그냥 자바 어플리케이션 실행하듯이 하면 되며, 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. Tip.

thrift 문서보다는 HBase 소스 코드를 다운로드 받아서 그 안에 있는 thrift server부분의 코드를 살펴보면 이해에 훨씬 도움이 될 것 이며, 다른 언어로 thrift server를 만들고 싶으시다면 thrift 소스 코드를 받으신 후에 tutorial 디렉토리에 있는 각 언어별 예제를 보시면 됩니다.

  • 초기에 thrift가 윈도우에 이식이 되지 않고, 비동기 I/O를 지원하지 않는 문제가 있었는데, 최근의 thrift 0.8.0에서는 두 가지 문제가 모두 해결되었다고 합니다.

에이브로

  • 이기종 간 데이터 타입을 교환할 수 있는 체계를 제공하는 프레임웍

  • C,CPP,Java,Php,Python,Ruby 지원
  • Apache Project
  • Hadoop
  • Thrift 처럼 RPC Transport Layer 지원
  • 메일링 리스트 활발하지 않음

제티

  • 관리자가 언제 어디서나 네트워크 장치 또는 이와 연결된 네트워크 관리를 가능하도록 한 것

외부 성능 테스트

https://github.com/eishay/jvm-serializers/wiki/