directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Directory Wiki] Update of "MinaTutorialInKorean" by CKoppelt
Date Thu, 15 Feb 2007 23:54:42 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Directory Wiki" for change notification.

The following page has been changed by CKoppelt:
http://wiki.apache.org/directory/MinaTutorialInKorean

------------------------------------------------------------------------------
- = MINA Tutorial: A Date with MINA =
+ deleted
  
- 글쓴이: 이 희 승
- 
- 역자: 이 동 철, 김상욱
- 
- 이 튜토리얼은 활발한 사용자의 참여를 위해 작성되었다. 초안으로
작성된 튜토리얼을 향상시키는 목적으로 자유롭게 이용하기 바란다.
- 
- == Table Of Contents ==
- 
- [[TableOfContents]]
- 
- == Overview ==
- 
- 지금은 WWW의 시대라 해도 과언이 아니다. 웹을 통한 서비스의 급격한
요구 증대는 무수히 많은 웹 애플리케이션 프레임웍들을 탄생시켰고
이는 개발 생산성 향상이라는 배경을 가지고 있다. 이러한 WWW의 위력에도
불구하고, 우리는 HTTP가 대체할수 없는 수많은 프로토콜이 존재함을
알고 있다. 그리고, HTTP는 그 중 하나에 불과하다. 우리는 여전히 적절한
프로토콜들을 구현하기 위한 C/S 애플리케이션을 개발해야만 한다.
- 
- === What is MINA? ===
- 
- 여러분들은 Java 를 이용해서 아니면 또 다른 개발 언어들을 이용하여
어떠한 프로토콜 스택을 구현한 적이 있는가? 여러분들도 격어보았겠지만
, 네트웍 애플리케이션들을 프로그램한다는 것은 전문 개발자들 조차도
그렇게 쉽지만은 않다. 그것은 몇가지 중요한 문제점들로 기인한다:
- 
-   * 개발자 생산성을 위해 고안된 적절한 네트웍 애플리케이션 프레임웍이
없다.
-     * 여러분들은 제한된 일정에 애플리케이션을 개발하기 어렵다.
-   * Network I/O code, message encoder/decoder 그리고 business logic은 쉽사리 서로간에
커플화되어져 있다.
-     * 여러분은 유지보수성과 재사용성을 잃는다.
-   * 네트웍 애플리케이션들은 단위테스트하기 난해하다.
-     * 여러분은 민첩성을 잃는다.
- 
- MINA는 성능 저하나 확장성 제약의 감수 없이도 위의 나열된 모든 이슈를
해결하기 위해 고안된 네트웍 애플리케이션 프레임웍이다.
- 
- == I/O Layer: Programming Echo Server ==
- 
- MINA는 두개의 layer로 구성되어 있다: I/O layer와 protocol layer. 먼저 우리는
I/O layer만을 이용하여 echo server를 구현하도록 해보자. 왜냐하면 protocol
layer는 일반적으로 I/O layer의 상위에 빌트온(built on)되어 있기 때문이다.
- 
- attachment:Arch1.gif
- 
- 위 다이어그램은 client와 MINA I/O layer 사이의 상호작용을 보여 주고
있다. IoAcceptor는 모든 low-level I/O를 수행하며, 그것들을 추상화된(abstract)
I/O event로 변환한다. 그리고 그 변환된 event를 연관된 IoSession과 함께
IoHandler에게 전달한다.
- 
- === IoSession ===
- 
- attachment:IoSession.gif
- 
- IoSession은 원격지와 여러분의 애플리케이션 사이의 I/O connection을 나타낸다.
IoSession을 이용하여, 여러분들은 원격지에 메세지를 작성할수 있으며,
세션 설정들에 접근이 가능하고 그 세션과 연관된 사용자 속성들을
저장할 수 있다.
- 
- === IoHandler ===
- 
- attachment:IoHandler.gif
- 
-   * sessionCreated: 새로운 I/O connection이 형성되어질때 호출된다. 이 메소드는
어떠한 I/O 오퍼레이션이라도 수행되기 전에 호출된다. 이런한 방식은
어떠한 socket 파라미터 또는 세션 속성이라도 먼저 셋업되어 질수 있도록
하기 위함이다.
-   * sessionOpened: sessionCreated가 호출된 후 그 다음 호출된다.
-   * sessionClosed: I/O connection이 끊어질 때 호출된다.
-   * sessionIdle: 원격지와 사용자 애플리케이션 사이에 어떠한 데이타
전송도 발생되지 않을때 호출된다.
-   * exceptionCaught: 어떠한 exception이 IoAcceptor 또는 IoHandler 으로부터 던져(throw)질때
호출된다.
-   * dataRead: 원격지로 부터 데이타가 읽혔을 때 호출된다.
-   * dataWritten: 원격지로 여러분이 작성한 write request가 보내졌을 때 호출된다.
- 
- 다음 섹션에서 우리는 echo protocol에서 사용하기 위한 IoHandler의 구현
방법에 대해 알아 보도록 할 것이다.
- 
- === Implementing IoHandler and Startup Code ===
- 
- 일반적으로, 여러분들이 작성하고자 하는 handler 메소드를 구현하기
위해 IoHandlerAdapter를 상속한다:
- 
- {{{
- package org.apache.mina.examples.echoserver;
- 
- import org.apache.mina.common.*;
- import org.apache.mina.io.*;
- import org.apache.mina.io.socket.*;
- 
- public class EchoProtocolHandler extends IoHandlerAdapter
- {
-     public void sessionCreated( IoSession session )
-     {
-         SessionConfig cfg = session.getConfig();
-         if( cfg instanceof SocketSessionConfig )
-         {
-             SocketSessionConfig scfg = ( SocketSessionConfig ) cfg ) ;
- scfg.setSessionReceiveBufferSize( 2048 );
-         }
-     }
- 
-     public void exceptionCaught( IoSession session, Throwable cause )
-     {
-         session.close();
-     }
- 
-     public void dataRead( IoSession session, ByteBuffer rb )
-     {
-         // Write the received data back to remote peer
-         ByteBuffer wb = ByteBuffer.allocate( rb.remaining() );
-         wb.put( rb );
-         wb.flip();
-         session.write( wb, null );
-     }
- }
- }}}
- 
- 방금 여러분들은 MINA를 이용한 echo protocol을 구현했다. 이제 여러분들은
작성한 handler를 server port에 바인딩해야 한다:
- 
- {{{
- package org.apache.mina.examples.echoserver;
- 
- import org.apache.mina.common.*;
- import org.apache.mina.io.*;
- import org.apache.mina.io.filter.*;
- import org.apache.mina.registry.*;
- 
- public class Main
- {
-     /** Choose your favorite port number. */
-     private static final int PORT = 8080;
- 
- 
-     public static void main( String[] args ) throws Exception
-     {
-         ServiceRegistry registry = new SimpleServiceRegistry();
- 
- // Bind
-         Service service = new Service( "echo",
- TransportType.SOCKET, PORT );
-         registry.bind( service, new EchoProtocolHandler() );
- 
-         System.out.println( "Listening on port " + PORT );
-     }
- }
- }}}
- 
- === Adding IoFilters ===
- 
- IoFilter는 MINA를 확장하기 위한 가장 막강한 방법을 제공한다. IoFilter는
모든 I/O 이벤트를 중간에 가로챈다. 그리고, 그 I/O 이벤트의 전-후 프로세스를
수행하도록 도와준다. 여러분은 Servlet 필터와 유사하다고 생각해도
된다. IoFilters는 다음과 같은 많은 목적으로 사용될 수 있다:
- 
-   * 이벤트 로깅
-   * 성능 프로파일링
-   * 데이터 전송(예를 들어 SSL 지원)
-   * 방화벽, ...
- 
- attachment:Arch2.gif
- 
- 우리의 echo protocol handler는 어떤 I/O 이벤트도 로깅(log)하지 않는다.
I/O 이벤트에 대한 로깅(log)을 위하여 filter를 추가함으로 해서 로깅(log)을
수행 할 수 있다. 다행히, MINA는 그러한 기능을 제공하기 위해 IoLoggingFilter를
제공한다. 자, ServiceRegistry에 logging filter를 붙여보자.
- 
- {{{
- private static void addLogger( ServiceRegistry registry )
- {
-     IoAcceptor acceptor =
- registry.getIoAcceptor( TransportType.SOCKET );
-     acceptor.getFilterChain().addLast( "logger",
-  new IoLoggingFilter() );
-     System.out.println( "Logging ON" );
- }
- }}}
- 
- 또, SSL은 어떤가? 또한, MINA는 Java 5 또는 그 상위에서 작동하는 SSL filter를
제공한다.
- 
- {{{
- private static void addSSLSupport( ServiceRegistry registry )
-         throws Exception
- {
-     SSLFilter sslFilter =
-         new SSLFilter( BogusSSLContextFactory.getInstance( true ) );
-     IoAcceptor acceptor =
-  registry.getIoAcceptor( TransportType.SOCKET );
-     acceptor.getFilterChain().addLast( "sslFilter", sslFilter );
-     System.out.println( "SSL ON" );
- }
- }}}
- 
- == Protocol Layer: Reversing the Echo ==
- 
- 우리는 단순한 echo 서버 예제를 통해 I/O 레이어를 어떻게 사용하는지를
배웠다. 그러나 여러분은 LDAP(Lightweight Directory Access Protocol)과 같은 복잡한
프로토콜을 어떻게 구현할지에 대해 생각해 봤는가? 그것은 악몽과도
같을 것이다. 왜냐하면 I/O 레이어가 메시지 코덱과 실제 비즈니스 로직(ex.디렉토리
데이터베이스를 액세스)을 분리시키는데 도움을 못 주기 때문이다.
MINA는 이러한 이슈를 해결하는 프로토콜 레이어를 제공한다. 이 프로토콜
레이어는 ByteBuffer 이벤트를 더 high-level 이벤트인 POJO 이벤트로 변환한다:
- 
- attachment:Arch3.gif
- 
- 여러분은 5개의 인터페이스를 구현해야 한다: ProtocolHandler, ProtocolProvider,
ProtocolCodecFactory, ProtocolEncoder, 그리고 ProtocolDecoder:
- 
- attachment:ProtocolClasses.gif
- 
- 어쩌면 이것은 너무 과하다고 생각될 수 있다. 그러나 ProtocolCodecFactory,
ProtocolEncoder, 그리고 ProtocolDecoder 는 완전하게 재사용 가능하다는 점을
주목하기 바란다. Apache ASN1 프로젝트는 MINA를 위한 ASN.1 코덱을 제공하고
있는 상태이고 MINA의 다음 배포버전에는 XML, Java Object Serialization, 그리고
단순한 텍스트와 같은 더 common한 코덱이 제공될 것이다. 일단 유연한
코덱을 구현하고 나면, 여러분은 그것을 미래에 새로운 애플리케이션에서
재사용할 수가 있다. 물론, 여러분의 코덱을 재사용할 계획이 없다고
하더라도, MINA는 복잡한 프로토콜을 구현할 수 있는 꽤 쉬운 방법을
제공한다. (이 문서의 Advanced Topics 부분을 참고하라)
- 
- 이 챕터에서 우리는 프로토콜 레이어 부분을 어떻게 프로그래밍해야
할 지를 보여주기 위해 "역방향(reverse)" 서버를 만들 것인데, 이 역방향
서버는 서버가 받는 텍스트 라인을 반대로(역방향으로) 출력한다.
- 
- === ProtocolSession ===
- 
- attachment:ProtocolSession.gif
- 
- ProtocolSession은 I/O 레이어의 IoSession에 상응하는 부분이다. 그림 X에서
짐작했겠지만, ByteBuffer 대신에 POJO로 메시지를 작성한다. ProtocolEncoder는
I/O 레이어가 메시지 객체를 밑에 있는 소켓에게 작성(write)할 수 있게
해당 메시지 객체를 ByteBuffers로 인코딩한다.
- 
- === ProtocolHandler ===
- 
- attachment:ProtocolHandler.gif
- 
- ProtocolHandler은 I/O 레이어의 IoHandler에 상응하는 부분이다. dataRead 메소드와
dataWritten 메소드는 각각 messageReceived 메소드와 messageSent 메소드를 대신한다.
이것은 ProtocolDecoder가 I/O 레이어에서 받은 ByteBuffers를 메시지 객체로
디코딩하기 때문이다.
- 
- === ProtocolEncoder and ProtocolDecoder ===
- 
- attachment:ProtocolCodec.gif
- 
- ProtocolEncoder와 ProtocolDecoder는 각각 하나의 메소드를 갖고 있다. ProtocolEncoder는
메시지 객체를 ByteBuffer로 인코딩하고, ProtocolDecoder는 ByteBuffers를 메시지
객체로 디코딩한다. 밑에서 우리는 이 인터페이스들을 어떻게 구현하는지에
대해 배울 것이다.
- 
- === Implementing ProtocolHandler ===
- 
- 먼저 ProtocolHandler를 구현하자. IoHandler를 구현할 때와 마찬가지로 여기에서도
우리는 ProtocolHandlerAdapter를 extend한다.
- 
- {{{
- package org.apache.mina.examples.reverser;
- 
- import org.apache.mina.protocol.*;
- 
- public class ReverseProtocolHandler extends ProtocolHandlerAdapter
- {
-     public void exceptionCaught( ProtocolSession session,
- Throwable cause )
-     {
-         // Close connection when unexpected exception is caught.
-         session.close();
-     }
- 
-     public void messageReceived( ProtocolSession session,
- Object message )
-     {
-         // Reverse received string
-         String str = message.toString();
-         StringBuffer buf = new StringBuffer( str.length() );
-         for( int i = str.length() - 1; i >= 0; i-- )
-         {
-             buf.append( str.charAt( i ) );
-         }
- 
-         // and write it back.
-         session.write( buf.toString() );
-     }
- }
- }}}
- 
- === Implementing ProtocolProvider and Setup Code ===
- 
- 이제 역방향 프로토콜을 구현하기 위해 유일하게 남은 인터페이스는
ProtocolProvider이다. 이것은 매우 간단하다.
- 
- {{{
- package org.apache.mina.examples.reverser;
- 
- import org.apache.mina.protocol.*;
- 
- /**
-  * {@link ProtocolProvider} implementation for reverser server protocol.
- */
- public class ReverseProtocolProvider implements ProtocolProvider
- {
-     // Protocol handler is usually a singleton.
-     private static ProtocolHandler HANDLER =
- new ReverseProtocolHandler();
- 
-     // Codec factory is also usually a singleton.
-     private static ProtocolCodecFactory CODEC_FACTORY =
- new ProtocolCodecFactory()
-     {
-         public ProtocolEncoder newEncoder()
-         {
-             // Create a new encoder.
-             return new TextLineEncoder();
-         }
- 
-         public ProtocolDecoder newDecoder()
-         {
-             // Create a new decoder.
-             return new TextLineDecoder();
-         }
-     };
- 
-     public ProtocolCodecFactory getCodecFactory()
-     {
-         return CODEC_FACTORY;
-     }
- 
-     public ProtocolHandler getHandler()
-     {
-         return HANDLER;
-     }
- }
- }}}
- 
- 이게 전부다. 이로써 Reverser 프로토콜은 완전하게 구현이 되었다. startup
코드는 에코 서버의 startup 코드와 매우 유사하다.
- 
- {{{
- package org.apache.mina.examples.reverser;
- 
- import org.apache.mina.common.*;
- import org.apache.mina.protocol.*;
- import org.apache.mina.registry.*;
- 
- /**
-  * (<b>Entry point</b>) Reverser server which reverses all text lines from
-  * clients.
-  *
-  * @author Trustin Lee (trustin@apache.org)
-  * @version $Rev: 165594 $, $Date: 2005-05-02 16:21:22 +0900 $,
-  */
- public class Main
- {
-     private static final int PORT = 8080;
- 
-     public static void main( String[] args ) throws Exception
-     {
-         ServiceRegistry registry = new SimpleServiceRegistry();
- 
-         // Bind
-         Service service = new Service( "reverse", TransportType.SOCKET, PORT );
-         registry.bind( service, new ReverseProtocolProvider() );
- 
-         System.out.println( "Listening on port " + PORT );
-     }
- }
- }}}
- 
- === Adding ProtocolFilters ===
- 
- ProtocolFilter는 I/O 레이어의 IoFilter에 상응하는 부분이다.
- 
- attachment:Arch4.gif
- 
- IoLoggingFilter를 add하면 디버깅 목적에 적합한 low-level I/O 이벤트에 대한
로그를 출력한다. 더 높은 high-level 이벤트에 대한 로그를 출력하려면
ProtocolLoggingFilter을 사용한다.
- 
- {{{
-     private static void addLogger( ServiceRegistry registry )
-     {
-         ProtocolAcceptor acceptor = registry.getProtocolAcceptor( TransportType.SOCKET );
-         acceptor.getFilterChain().addLast( "logger", new ProtocolLoggingFilter() );
-         System.out.println( "Logging ON" );
-     }
- }}}
- 
- == Advanced Topics ==
- 
- 여기에서는 보다 MINA를 깊게 알고자 하는 사용자들을 위한 상급 토픽(advanced
topics)을 다룬다.
- 
- === ByteBuffers ===
- 
- MINA는 자바 NIO ByteBuffer를 직접적으로 사용하지 않는다. 자바 NIO ByteBuffer의
기능을 확장하는 커스텀 ByteBuffer 클래스를 사용한다. Java NIO ByteBuffer와
커스텀 ByteBuffer의 몇가지 차이점은 다음과 같다.
- 
-   * MINA ByteBuffer는 사용자들이 자유롭게 확장할 수 있는 추상 클래스이다.
-   * MINA는 MINA ByteBuffers를 관리하고 풀링한다. acquire()와 release() 메소드를
제공함으로써 사용자들은 버퍼가 릴리즈되는 시점을 조절할 수 있다.
-   * MINA ByteBuffer는 unsigned 값의 getter와 스트링 getter & putter와 같은
편리한 메소드들을 제공한다.
- 
- 여러분이 만약 MINA를 쓴다면, NIO 버퍼를 직접적으로 쓸 필요가 절대
없을 것이다. 왜냐하면 거의 모든 버퍼 관련 작업을 MINA 버퍼만으로
할 수 있기 때문이다.
- 
- ==== ByteBuffer pooling ====
- 
- MINA는 하나의 가상머신에서 실행중인 모든 MINA 애플리케이션들이 공유하는
Global ByteBuffer Pool을 갖고 있다. 할당된 모든 버퍼는 I/O 작업 혹은 이벤트
핸들러 메소드가 수행되거나 invoke된 후에 릴리즈된다. 그러므로 Pool에서
빈(clean) 퍼버를 얻기 위해서는 단순히 ByteBuffer.allocate()를 호출하면 되고
버퍼를 풀에 반환하는 것에 대해서는 신경 안 써도 된다. 더욱 세부적인
내용은 ByteBuffer JavaDocs을 참고하기 바란다.
- 
- === Thread Model ===
- 
- MINA는 MINA의 다양한 필터 메카니즘을 사용함으로써 다양한 쓰레딩
모델을 지원한다. 쓰레드 풀 필터가 하나도 추가되지 않았을 때에는
싱글 쓰레도 모드 상태에서 작동한다. IoThreadPoolFilter 하나를 IoAcceptor에
추가하면 하나의 리더-추종자(leader-follower) 방식의 쓰레드 풀이 생긴다.
ProtocolThreadPoolFilter를 하나 더 추가하면, 여러분의 서버는 두 개의 쓰레드
풀을 가질 것이다; 메시지 객체를 디코딩하는 풀(IoThreadPoolFilter)과 비즈니스
로직을 수행하는 풀(ProtocolThreadPoolFilter).
- 
- SimpleServiceRegistry는 IoThreadPoolFilter와 ProtocolThreadPoolFilter를 추가하는데
이는 애초에 높은 확장성을 요구하는 애플리케이션에 적합하다. 만약
여러분의 (여러분이 직접 구현한) 쓰레딩 모델을 사용하고 싶다면, SimpleServiceRegistry의
소스 코드를 참고하고 Acceptors를 직접 초기화시켜라. 물론 이것은 매우
간단한 작업이다.
- 
- {{{
- IoThreadPoolFilter threadPool = new IoThreadPoolFilter();
- threadPool.start();
- 
- IoAcceptor acceptor = new SocketAcceptor();
- acceptor.getFilterChain().addLast( "threadPool", threadPool );
- 
- ProtocolThreadPoolFilter threadPool2 = new ProtocolThreadPoolFilter();
- threadPool2.start();
- 
- ProtocolAcceptor acceptor2 = new IoProtocolAcceptor( acceptor );
- acceptor2.getFilterChain().addLast( "threadPool", threadPool2 );
- 
- ...
- 
- threadPool2.stop();
- threadPool.stop();
- }}}
- 
- 
- === More Complex Protocols ===
- 
- 역방향 (Reverser) 예제는 다른 복잡한 프로토콜들에 비해 너무 간단하다.
수십가지의 메시지 타입이 존재할 것이고 그에 따라 서버를 작동시키는
수십가지의 코덱이 존재할 것이다. MINA는 다음과 같은 유틸리티 클래스를
제공한다.
- 
-   * DemuxingProtocolHandler
-   * DemuxingProtocolCodecFactory
- 
- 세부적인 내용은 JavaDocs을 참고하기 바란다.
- 
- === In-VM Pipe Communication ===
- 
- 여러분은 프로토콜 레이어가 I/O 레이어 위에 구축된다는 것을 배웠다.
하지만 이는 전적으로 옳은 말은 아니다. 우리가 보통 I/O 레이어를 감싸는
(wraps) 프로토콜 레이어를 사용하긴 하지만, 여기에는 "in-VM pipe communication"이라
불리는 프로토콜 레이어의 특별한 구현체가 존재한다.
- 
- 여러분이 SMTP 서버와 스팸 필터 서버를 MINA로 구현했다고 가정하자.
SMTP 서버는 스팸 메시지를 탐지하거나 RBL(Realtime Blackhole List)에 속하는
클라이언트(메일 송신자)를 탐지하기 위해 아마도 스팸 필터 서버와
커뮤니케이션을 할 것이다. 만약 이 두 서버가 동일한 자바 가상머신에
있다면, I/O 레이어는 필요가 없다; 여러분은 메시지 객체를 인코딩 &
디코딩을 할 필요없이 단순히 우회시키기만(bypass) 하면 된다. In-VM pipe
communication은 스팸 필터 서버가 동일한 VM에 있는지 없는지에 관계없이
동일한 코드를 사용할 수 있게 한다.
- 
- 소스 배포판에 있는 "테니스" 예제를 참고하기 바란다.
- 
- == How to Contribute ==
- 
- We want MINA to evolve actively, reacting to user requests, and therefore we need as much
feedback from you as possible.  The Apache Directory team will strive to satisfy all possible
use cases of MINA.  Please feel free to contact us.
- 
- === How to Contact Us ===
- 
-   * Mailing list: dev@directory.apache.org (Please use ‘[mina]’ prefix)
-   * Issue tracker: http://issues.apache.org/jira/browse/DIRMINA
- 
- === How to Report Bugs ===
- 
- You can report any bugs found from MINA to our issue tracker page.  Please attach any test
cases that can reproduce your issue if possible.
- 
- === How Issues ===
- 
- Any patches and comments are welcome!  You can browse the list of unresolved issues in JIRA:
- 
-   * http://issues.apache.org/jira/browse/DIRMINA
- 
- Or, you could do some performance benchmarks on MINA and tune it.
- 
- == Acknowledgements ==
- 
- MINA couldn’t exist without strong support of many contributors:
- 
-   * The Apache Directory team for letting me join the team
-   * All users of Netty2 forum and dev@directory.apache.org for great feedbacks
-   * Jan Andersson and his team for SSLFilter
-   * Vel Pandian for enabling client mode for SSLFilter
-   * Vinod Panicker for performance benchmark and active feedbacks
- 

Mime
View raw message