2011년 2월 20일 일요일

백업] 네이버 36

링크가 다 깨져버렸다...

키워드는 아까워서 남겨둠.

분산 객체는 일반적인 자바 객체와는 다르게 다른 JVM에서 리모트로 접근할 수 있는
객체
를 말합니다. 일반적으로 객체는 하나의 JVM 내에서 생성되어 사용되는데,
이런 객체를 로컬 객체라 합니다.
다른 시스템에서 분산 객체를 리모트로 할 때
로우 레벨의 네트워크 관련 코드로써 분산 객체를 사용하는 것이 아니라, 단순하게
로컬 객체를 사용하듯이 메소드를 호출하는 형태임
분산 객체를 사용하는 쪽에서는 분산 객체에 대한 리모트 레퍼런스(Remote
Reference)를 얻어, 이 리모트 레퍼런스를 이용해 마치 로컬에 있는 객체처럼 분산
객체의 메소드를 호출함
분산 객체 기술
RPC (Remote Procedure Call)에서 유래됨
RPC와 마찬가지로 스텁·스켈레톤간의 통신으로 처리함
스텁을 분산 객체에 대한 클라이언트 사이드 프락시라 하고, 스켈레톤은 서버측
프락시
라 하는데, 이것은 대개 벤더 툴로 생성함
벤더 툴에 의해 네트워크 관련 로우 레벨 코드가 생성되고, 약속에 의해 개발되기
때문에 프로그래밍 하기 쉬움
자바 분산 객체 기술로는 RMI(Remote Method Invocation), JavaIDL, 엔터프라이즈
자바 빈이 있는데, 엔터프라이즈 자바 빈은 RMI 분산 객체 기술을 기반으로 함


 

RMI는 자바 분산 객체 기술로써, 분산 객체를 정의하고 실행하기 위한 환경을 제공하는데
J2SE(Java2 Standard Edition)에 기본 아키텍쳐가 구현되어 있습니다. 그래서 JDK외의
별도 툴이나 제품을 필요로 하지 않습니다.



RMI는 자바 분산 객체 기술로써, 분산 객체를 정의하고 실행하기 위한 환경을 제공하는데
J2SE(Java2 Standard Edition)에 기본 아키텍쳐가 구현되어 있습니다. 그래서 JDK외의
별도 툴이나 제품을 필요로 하지 않습니다.

RMI
리모트 JVM에서 레퍼런스를 얻어 메소드 호출을 할 수 있는데, 이때 내부적으로는
RPC와 같이 스텁·스켈레톤 간의 통신으로 처리함
(스텁·스켈레톤에 네트워크 로우 레벨 코드가 구현)
장점:
네트워크 및 서버 프로그래밍 방법을 몰라도 약속에 의해 쉽게 분산 객체를
개발할 수 있음
분산 객체의 메소드 호출 시 파라미터와 리턴 값의 전달은 “pass by value”, “pass by reference” 두 가지 방식을 지원함 (내부적으로 객체 직렬화를 이용하는데, 로컬
객체가 전달될 때에는 “pass by value”로 전달되고, 분산 객체가 전달될 때는
“pass by reference” 방식으로 전달됨
)
RMI의 구성
서버
분산 객체를 생성해서 분산 객체를 서비스하는 어플리케이션
클라이언트
분산 객체의 레퍼런스를 얻어 서버의 분산 객체를 사용하는
어플리케이션
네이밍 서비스
분산 객체의 리모트 레퍼런스(Remote Reference)는 네이밍
서비스를 통해 클라이언트에 전달됨 
네이밍 서비스는 분산 객체 기술에서 반드시 필요한 부분임
RMI는 일반적인 호출 기법 이외에도 여러 가지 프로그래밍 패턴에 따라 다음과 같은 기술이
소개되고 있습니다.
기술 설명
Agent
다른 시스템에 전달되어 그곳에서 작업을 해서 데이터를 수집해 오는 객체
Agent 객체는 로컬 객체로 다른 시스템에 pass by value 형태로 전달 되고, 이 Agent 객체를 다른 시스템에 전달하기 위해서 분산 객체의 리모트
메소드를 이용
Factory
서버에서 서비스하는 여러 분산 객체를 모두 생성한 후 네이밍 서비스에
등록해 서비스를 기다리는 것이 아니라, 여러 분산 객체를 필요한
클라이언트의 요청에 의해 생성, 반환하는 기능을 갖는 분산 객체
Activation
여러 분산 객체를 서비스하는 서버 어플리케이션의 메모리 리소스를
효율적으로 관리하기 위해 클라이언트가 요청하는 분산 객체를
생성하고 서비스하는 기술
JDK 1.2에서 API가 추가된 기술
Call back
여러 클라이언트에 메시지를 이벤트 형태로 브로드캐스팅 할 수 있는
디자인 패턴
채팅이나 여러 서버의 데이터를 관리하는 관리 툴을 개발할 때 이용
Remote
Loaded
Stub
스텁 클래스를 클라이언트가 직접 갖고 실행되는 것이 아니라 실행 시
리모트에 있는 웹 서버, 혹은 FTP 서버로부터 다운 받아 실행되는 기술





RMI 아키텍쳐는 어플리케이션 계층, 스텁·스켈레톤 계층, 리모트 레퍼런스 계층,
트랜스포트 계층으로 구성됩니다.
구성 요소: 리모트 인터페이스, 서번트(분산 객체), 서버, 클라이언트 어플리케이션
서버 어플리케이션은 분산 객체를 생성해서 네이밍 서비스에 등록함
클라이언트 어플리케이션은 네이밍 서비스로부터 분산 객체의 리모트 레퍼런스를
얻어내어 분산 객체의 메소드 호출을 요청함
분산 객체가 서비스하는 메소드는 리모트 인터페이스(Remote Interface)로 정의
클라이언트는 분산 객체의 구현에 대해 알 필요가 없음
단지 분산 객체가 서비스하는 메소드 명세서만 알면 되기 때문에 클라이언트는
분산 객체의 리모트 인터페이스만을 갖고 개발함
서버에서 분산 객체를 생성하면 내부적으로 UnicastRemoteObject.exportObject()
메소드 호출
메소드는 분산 객체의 스텁 객체를 생성하고, 분산 객체의 정보를 RMI 시스템에
전달
하고 전달된 분산 객체 정보는 분산 가비지 컬렉션(Distributed Garbage Collection)을 위해 관리함
클라이언트가 분산 객체의 리모트 레퍼런스인 스텁 객체를 얻는 과정
서버가 네이밍 서비스를 통해 등록한 스텁 객체를 전달함







RMI에서 분산 객체 메소드 파라미터, 반환 값을 전달하는 방식은 다음 두 가지 방식을
지원합니다.
로컬 객체와 분산 객체가 전달될 때
로컬 객체
전달될 객체의 복사본이 객체 직렬화로 전달
객체의 복사본이 전달된 형태로 Pass by Value 형태의 전달
분산 객체
전달될 분산 객체의 스텁 객체 복사본이 객체 직렬화로 전달
분산 객체의 리모트 레퍼런스로 동작하는데, 이것은 Pass by reference 형태의 전달을 의미







RMI는 약속에 의해 쉽게 프로그래밍할 수 있다는 장점이 있습니다. RMI 프로그래밍 방법은
다음과 같이 정리해 볼 수 있습니다.
RMI 프로그래밍 방법에 대한 각 단계별 내용을 살펴보겠습니다.







리모트 인터페이스는 분산 객체에 대한 클라이언트 인터페이스를 말합니다.
RMI 클라이언트는 분산 객체를 리모트 인터페이스 타입으로 보고 개발, 실행됩니다.
결국, 리모트 인터페이스는 분산 객체가 어떤 메소드를 리모트로 서비스 하는지에 대한
명세서(Specification)
라고 할 수 있습니다. 
리모트 인터페이스의 개발 방법
리모트 인터페이스 소스
개발할 분산 객체가 sayHello() 라는 리모트 메소드를 제공함
리모트 인터페이스는 분산 객체가 서비스하는 리모트 메소드를 갖는 분산 객체에 대한
명세서임








서번트는 분산 객체를 말하는데, 앞에서 정의한 분산 객체의 명세서인 리모트 인터페이스를
구현해야 합니다.
서번트 클래스의 개발 방법
서번트 클래스는 앞 단계에서 정의한 리모트 인터페이스를 구현하는 클래스로 리모트
인터페이스에 정의한 리모트 메소드의 몸체를 구현함
서번트 클래스 이름을 정의할 때 위에서 정의한 리모트 인터페이스 이름에 “Impl”을
붙임 (일종의 네이밍 규칙)
서번트 클래스 소스







서버 어플리케이션은 클라이언트를 위해 분산 객체를 생성하고, 생성한 분산 객체를
네이밍 서비스에 등록하는 어플리케이션입니다.
서버 어플리케이션에 구현해야 할 내용
분산 객체의 생성은 일반 객체를 생성하는 것과 동일함
(new라는 키워드와 생성자 함수를 통해 객체를 생성)
분산 객체를 네이밍 서비스에 등록할 때 Naming.rebind() 메소드를 이용함
네이밍 서비스의 key, value를 쌍으로 하여 분산 객체를 관리함
등록할 때 key, value를 쌍으로 등록하고, 분산 객체를 네이밍 서비스로부터 얻어낼
때는 key 값을 이용함
key는 다음과 같은 URL 형태를 취함
rmi://ip:port/name
서버 어플리케이션 소스
네이밍 서비스가 서버와 같은 위치에 있고 디폴트 포트를 사용하기 때문에
Naming.rebind()에 첫 파라미터는 분산 객체의 이름만 명시함







클라이언트는 분산 객체에 대한 실제 구현을 알 필요가 없습니다. 분산 객체가 어떤
메소드를 서비스 하는지만 알면 됩니다. 즉, 서번트 클래스는 클라이언트에게는 필요하지
않고, 리모트 인터페이스만으로 클라이언트 어플리케이션이 개발됩니다.
클라이언트 어플리케이션의 개발 절차
클라이언트 어플리케이션 소스







개발된 4개의 소스를 다음 그림과 같이 작업 디렉토리에서 컴파일하고, 그 결과 생성되는
클래스를 확인해 봅니다.
※ 아래 화살표를 클릭하세요.







스텁 · 스켈레톤은 분산 객체의 대리인(Proxy)으로 코드를 직접 개발하는 것이 아니라 툴로
생성합니다. J2SE 내에 rmic 라는 컴파일러를 제공하는데, 이것은 서번트 클래스를
이용하여 스텁 · 스켈레톤 클래스를 생성합니다
rmic 컴파일러를 이용해 스텁 · 스켈레톤 클래스 생성
도스 창에서 rmic 컴파일러를 이용해 스텁 · 스켈레톤 클래스를 생성함
HelloImpl 클래스를 이용하여 rmic로 컴파일 하면, HelloImpl_Stub.class, HelloImpl_Skel.class가 생성됨
생성된 클래스의 소스를 볼 때: prompt>rmic -keep HelloImpl






RMI 어플리케이션은 서버, 클라이언트, 네이밍 서비스의 세가지 부분으로 구성되는데,
다음과 같이 순서대로 실행해야 합니다.
앞에서 개발한 여섯 개의 클래스가 위 세 부분에 모두 필요한 것은 아닙니다.
서번트 클래스의 경우, 분산 객체의 실제 구현 코드를 가지는 클래스로 클라이언트가 알 필요가 없는 클래스입니다.
개발된 클래스의 배치
Naming Service Hello.class, HelloImpl_Stub.class
Server Application Hello.class, HelloImpl_Stub.class, HelloImpl_Skel.class,
RMIServer.class
Client Application Hello.class, HelloImpl_Stub.class, RMIClient.class






RMI 어플리케이션에서 네이밍 서비스는 분산 객체의 리모트 레퍼런스를 서비스합니다.
이 네이밍 서비스는 RMI 클라이언트를 위해서만 필요한 것이 아니라, 서버가 분산 객체를
등록할 때에도 필요하기 때문에 가장 먼저 실행해야 합니다.
네이밍 서비스
J2SE 내에 rmiregistry라는 명령어로 제공함
(rmiregistry 네이밍 서비스는 서버가 실행되는 시스템에서만 동작을 시켜야 함)
디폴트로 1099 포트를 할당 받아 실행됨
네이밍 서비스 실행
아래 그림은 도스 창에서 rmiregistry에 대한 옵션을 확인하고, rmiregistry를 실행한
화면임
-J-Dsun.rmi.loader.logLevel=VERBOSE는 rmiregistry의 로그를 화면으로 출력하는
옵션임
Rmiregistry에 등록되는 객체가 어떤 클래스인지를 확인할 수 있음






서버 어플리케이션
생성한 분산 객체를 네이밍 서비스에 등록함
자동으로 클라이언트의 요청을 리슨(Listen)하기 위해 웨이트(Wait) 상태로 됨
구현한 실제 코드는 두 라인이지만 내부적으로는 스텁 객체가 생성되고, 생성된 분산
객체의 정보가 RMI 시스템으로 전달됨
서버 어플리케이션 실행
다음과 같이 작업 디렉토리에서 서버 어플리케이션을 실행함
아래 결과에서 “The server is ready…” 라는 스트링이 화면에 출력된 것으로
보아 분산 객체를 생성해 네이밍 서비스에 등록했다는 것을 알 수 있음







마지막으로 클라이언트 어플리케이션 실행에 대하여 알아보도록 하겠습니다.
클라이언트 어플리케이션 실행
RMI 클라이언트는 rmiregistry로부터 분산 객체의 리모트 레퍼런스를 얻어내, 분산
객체의 메소드를 호출함
작업 디렉토리에서 RMI 클라이언트 어플리케이션을 실행함
 
     <클라이언트 어플리케이션 실행 결과>
서버 쪽 윈도우에 “Received Msg : haha” 라고 출력된 것으로 보아 클라이언트의
메소드 호출 결과로 분산 객체의 메소드가 서버 쪽에서 실행된 것을 확인할 수
있음
    <클라이언트 실행 후 서버 윈도우 화면>
클라이언트가 얻어낸 스텁 객체는 서버에서 분산 객체가 생성될 때 내부적으로
생성되어 네이밍 서비스를 통해 클라이언트까지 전달된 것임
 




자바 분산객체 기술
분산 객체
리모트로 접근 가능한 객체
내부적으로는 스텁, 스켈레톤 간의 통신
분산 객체와 로컬 객체의 비교
RMI (Remote Method Invocation)
자바 분산 객체 기술
분산 객체를 정의하고 실행하기 위한 환경을 제공
J2SE(Java2 Standard Edition)에서 기본 아키텍쳐를 구현
RMI 서버, 클라이언트, 네이밍 서비스의 세 부분으로 구성
RMI 아키텍쳐
어플리케이션 계층
리모트 인터페이스, 서번트(분산객체), 서버, 클라이언트 어플리케이션으로 구성
서버 어플리케이션은 분산객체를 생성해서 네이밍 서비스에 등록
클라이언트 어플리케이션은 네이밍 서비스로부터 분산객체의 리모트 레퍼런스를
얻어내어 분산객체의 메서드 호출을 요청
스텁/스켈레톤 계층
RMI 시스템과 어플리케이션 계층간 인터페이스 역할
rmic 컴파일러를 통해 스텁/스켈레톤 코드 생성
스텁은 분산 객체의 대리인(Proxy)
통신을 통해 데이터를 전달하고, 받기 위한 마샬 스트림(Marshal Stream) 사용
마샬 스트림으로 데이터를 보내는 과정을 마샬링(Marshalling)
마샬 스트림으로부터 데이터를 읽어 복원하는 과정을 언마샬링(Unmarshalling)
리모트 레퍼런스 계층
분산 객체의 메서드 호출의 의미를 전달
분산 객체의 레퍼런스를 관리
메서드 호출을 처리하는 과정에 네트웍 커넥션이 이상이 있을 경우 재 연결 관리
트랜스포트 계층
로우 레벨 네트웍 커넥션 유지, 모니터링
서버 사이드에서는 분산객체의 호출을 처리
분산객체의 레퍼런스를 테이블로 관리
RMI 단계별 개발 절차
리모트 인터페이스 개발
java.rmi.Remote interface를 extends
분산 객체가 리모트로 서비스 하려는 메서드를 선언
선언되는 메서드는 반드시 java.rmi.RemoteException을 던지게 정의
서번트 클래스 개발
정의한 리모트 인터페이스를 구현
java.rmi.server.UnicastRemoteObject 클래스를 상속
생성자 함수는 java.rmi.RemoteException을 던지게 정의
서버 어플리케이션 개발
분산 객체인 서번트를 생성
생성한 분산 객체를 네이밍 서비스에 등록
클라이언트 어플리케이션 개발
네이밍 서비스로부터 분산 객체의 리모트 레퍼런스 획득
분산 객체가 제공하는 리모트 메서드 호출
개발한 프로그램 컴파일
스텁, 스켈레톤 클래스 생성
rmic 라는 컴파일러를 통해 서번트 클래스의 스텁, 스켈레톤 클래스 생성
RMI 프로그램 실행 절차
네이밍 서비스 실행
J2SE 내에 rmiregistry 사용
rmiregistry 네이밍 서비스는 서버가 실행되는 시스템에서 동작
디폴트로 1099 포트를 할당 받아 실행
서버 어플리케이션 실행
생성한 분산 객체를 네이밍 서비스에 등록
클라이언트의 요청을 리슨하기 위해 웨이트(wait) 상태 유지
클라이언트 어플리케이션 실행
rmiregistry로부터 분산 객체의 리모트 레퍼런스 획득
분산 객체의 메서드를 호출

댓글 없음:

댓글 쓰기

국정원의 댓글 공작을 지탄합니다.

UPBIT is a South Korean company, and people died of suicide cause of coin investment.

 UPBIT is a South Korean company, and people died of suicide cause of coin. The company helps the people who control the market price manipu...