java - RMI

Development/Java 2012. 1. 17. 09:35

 RMI (Remote Method Invocation) ; 원격 메쏘드 호출 

RMI는 자바 프로그래밍 언어와 개발환경을 사용하여 서로 다른 컴퓨터들 상에 있는 객체들이 분산 네트웍 내에서 상호 작용하는 객체지향형 프로그램을 작성할 수 있는 방식이다. RMI는 일반적으로 RPC라고 알려져 있는 것의 자바 버전이지만, 그러나 요청과 함께 하나 이상의 객체들을 통과시키는 능력을 가지고 있다. 객체는 원격 컴퓨터 내에서 수행될 서비스를 변경하는 정보를 포함할 수 있다. 자바를 발명한 회사인 썬 마이크로시스템즈에서는 이것을 "움직이는 작용"(moving behavior)이라고 부른다. 예를 들면, 원격 컴퓨터에 있는 사용자가 비용 청구서를 채울 때, 사용자와 상호작용을 하는 자바 프로그램은 RMI를 사용하여 비용 보고에 관해 항상 최신 방침을 가지고 있는 다른 컴퓨터의 자바 프로그램과 통신할 수 있을 것이다. 이에 답하여, 그 프로그램은 최신 방침에 위반됨이 없는 방식으로 사용자의 비용 청구서 데이터를 심사하는 원격 컴퓨터 프로그램의 이용을 허락하는 객체와, 관련 메쏘드 정보를 돌려보낼 것이다. 사용자와 회사는 둘 모두 초기에 실수를 예방함으로써 시간을 절약할 수 있게 된다. 회사의 방침이 변경될 때마다, 오직 한 컴퓨터에 있는 프로그램만 변경하면 된다.

썬은 그것의 객체 매개변수 전달 방식을 객체 직렬화라고 부른다. RMI 요청은 원격 객체의 메쏘드를 부르는 요청이다. 이 요청은 지역 컴퓨터 내에 객체 메쏘드를 부르는 것과 같은 구문 형식을 가진다. 일반적으로, RMI는 네트웍에 걸쳐 있는 객체 모델과 그것의 장점들을 보호하기 위해 설계된다.

RMI는 응용프로그램과 자바 가상머신 사이에 세 개가 계층으로 구현된다. 그 세 가지 계층이란 다음과 같다.

  • 클라이언트/서버 관계의 클라이언트 측에 있는 스터브 프로그램과, 서버 측에서 대응하는 조직. 호출하는 프로그램에게 스터브는 서비스를 위해 호출되는 프로그램으로 보이게 된다 (썬은 스터브와 비슷한말로 프럭시라는 용어를 사용한다)..
  • Remote Reference Layer는 호출하는 프로그램에 의해 전달된 매개변수에 따라 다르게 행동할 수 있다. 예를 들면, 이 계층은 그 요청이 단일 원격 서비스를 호출하는 것인지 또는 멀티캐스트에서 다중 원격 프로그램을 호출하는 것인지를 결정할 수 있다.
  • Transport Connection Layer는 이 요청을 설정하고 관리한다.

단일 요청은 한 컴퓨터 상에 있는 계층들을 통하여 아래로 내려오며, 다른 쪽에 있는 컴퓨터의 계층들을 통하여 위로 올라간다. RMI는 썬 마이크로시스템즈의 JDK의 일부로서 공급된다.

 







자바 원격 함수 호출

위키백과, 우리 모두의 백과사전.

자바 원격 함수 호출(Java Remote Method Invocation, Java RMI)는 자바 프로그램에서 각
객체간, 컴퓨터간 메서드를 호출할 수 있게 해주는 기술이다.

[편집]개요

  • 서로 다른 JVM상에 있는 객체의 메소드를 호출함.
  • RMI는 전송 계층을 은폐함. ==> 투명성 보장
  • 소켓상의 통신

자바만을 위한 최초의 프로토콜은 JRMP (Java Remote Method Protocol) 이었다. 이후 공통적인
객체를 호출하기 위해 CORBA (Common Object Request Broker Architecture)가 개발되었다.
이후 CORBA의 IIOP를 받아들여 RMI가 개발되었다. 현재 RMI-IIOP는 JRMP 구현과 그 인터페이스
는 동일하지 않다.

자바 원격 함수 호출 API(Java RMI)는 자바 응용프로그램을 짜는 인터페이스이다. 이것은 공통적인
객체를 호출하기 위해 사용된다. 이API는 보통 두가지 실시방법이 있다. 최초의 실행방법은 Java
Virtual Machine (JVM) 클래스 표현 구조를 의지한다. 그러므로 이방식은 한JVM에서 다른
JVM에로의 호출만 지원한다. 이런 자바에서만 실행되는 프로토콜은 Java Remote Method
Protocol (JRMP)로 알려져있다. 코드가 JVM환경 밖에서도 운행시키기 위해 CORBA (Common
Object Request Broker Architecture)가 개발되었다.

다른 추천하는 RMI의 버전은 Jini이다. 이것은 앞의것과 비슷하지만 더욱많은 찾기능력과 분산
오브젝트 애플리케이션 기법을 지원한다.

[편집]바깥 고리

  • Cajo A framework for transparent, dynamic cooperation between Java Virtual Machines



 




RMI란?

- 원격 메서드 호출이란 로컬 컴퓨터에서 원격 컴퓨터의 메서드를 호출하는 기술이다.

실제 클라이언트에서 원격 컴퓨터에 존재하는 메서드를 호출할 것이고, 클라이언트가 원격 메서드를 호출 했을때 원격 컴퓨터의 CPU를 사용하며, 클라이언트는 그 결과값만을 네트웍으로 전송받는다.


RMI의 데이터 전달 기법은?

-매개변수와 반환값이 없는 메서드의 호출은 의미가 없습니다. 로컬 머신에서 원격으로 메서드를 호출하더라도 매개변수를 RMI 통신을 통해서 날려주고, 그리고 리턴값을 다시 되돌려 받아야 합니다. 이것을 해결하기 위해서 RMI 내부에서는 객체 직렬화(Serialization)의 기법을 이용합니다. 매개변수로 넘겨 줄 객체를 직렬화한 후 메서드를 호출할 때 함께 보내주는 것입니다. 그리고 그 결과값 또한 직렬화되어 원격 컴퓨터로부터 반환됩니다.


RMI모델

- RMI를 구축하기 위해서는 원격지의 컴퓨터에 RMI Server가 필요하다. 이 RMI Server에 객체를 넣어두고 (바인딩) 로컬 머신에서 접근한 후 객체의 메서드를 호출하는 것이다. 기본적으로 RMI Registry라는 서버모델이 제공 되기는 하나 이것은 단순 개발용이고, 일반적으로 RMI기반의 모델 중 가장 널리 알려진 것이 바로 EJB를 서비스해주는 J2EE모델이다. J2EE기술은 비지니스 로직을 처리하기 위한 RMI 기반의 응용 모델이며, 여기서 서비스 되는 객체를 EJB라고 한다.


▣ RMI Registry 
◈ 자바 RMI는 원격 객체를 관리하고 서비스하는 원격 객체 컨테이너(Container)를 제공하는데, 이것을 RMI Registry라고 한다.

▣ 바인딩(Binding) 
◈ RMI Registry에 원격 객체를 등록하는 과정을 바인딩(Binding)이라고 한다. 
◈ RMI Registry에 원격 객체를 등록할 때에는 객체를 식별할 수 있는 식별자(Name)와 함께 등록해야 한다. 

- J2EE상업 모델 중 가낭 잘 알려진 것이 웹로직이다.


클라이언트의 원격 참조 객체는 그냥 만들어지는 것이 아니고 클라이언트로부터 LookUp이라는 과정을 통해 서버로부터 내려받아야 한다. 이 룩업은 원격 객체의 바인딩 과정에서 사용한 식별자(Name)를 사용하여 RMI Registry에 존재하는 객체를 클라이언트 측에서 검색하는 작업이다. 그리고 클라이언트가 이 원격 객체를 LookUp하였을때 RMIRegistry는 원격객체를 대신 할 원격참조객체를 클라이언트에 보내주게 되며, 클라이언트는 이 원격참조객체를 통하여 원격객체를 호출 하는 것이다.



RMI만들기.

1.원격 인터페이스의 작성

-원격 인터페이스는 원격 객체가 사용 할 메서드를 명시하는 과정임.

▣ 원격 인터페이스 
◈ public interface IHello extends Remote{ 
◈        public String sayHello(String name) throws RemoteException; 
◈ } 
- 여기에 명시된 메서드만이 원격으로 호출이 가능하다.

- 위의 이유로 이 인터페이스는 클라이언트측에 공개 되어야 한다.(수동으로...메일이든 뭐든..)

- Remote를 상속하며, RemoteException처리를 해주어야 한다.(규약)


2.원격 클래스 만들기

- 원격 인터페이스를 구현해야 한다.

- UnicastRemoteObject클래스를 상속해야 한다.

▣ 원격 클래스의 실제 구현 
◈ public class HelloImpl extends UnicastRemoteObject implements IHello { 
◈         public HelloImpl() throws RemoteException { } 
◈         public String sayHello(String name) throws RemoteException{ 
◈             System.out.println(name + "님 안녕하십니까! "); 
◈             return name + "님 안녕하십니까! "; 
◈         } 
◈ }

- 생성자에도 Exception처리가 있음을 주의

- 인터페이스인 IHello를 구현하고 있다.


3.Stub 클래스 만들기

- 클라이언트가 사용하는 원격 참조 객체를 만들기 위해서는 스텁(Stub)클래스가 필요하다.

- 이 스텁 클래스로 객체를 만들면 원격 참조 객체(가짜 객체)가 되는 것이다.

- 제공되는 rmic.exe라는 툴을 사용한다.

javac HelloImpl.java

rmic HelloImpl

▣ rmic.exe로 생성된 스텁(Stub)과 스켈레톤(Skeleton) 파일 
◈ HelloImpl_Stub.class 
◈ HelloImpl_Skeleton.class 

-Java 1.2이후에서는 Stub클래스에 스켈레톤 클래스의 기능이 통합되어 있으며, 버젼 유지를 위해 현재도 스켈레톤 클래스는 같이 생성된다.


4.스텁과 스켈레톤을 사용하여 바인딩 시키기

- 스텁과 스켈레톤까지 작성했다면 원격 클래스를 이용하여 원격 객체를 만든 후 RMI Registry에 바인딩 시키는 서버 프로그램이 필요하다


▣ 바인딩을 위한 서버 프로그램의 구현 
import java.rmi.*; 
import java.rmi.server.*; 
public class HelloRMIServer{ 
    public static void main(String[] args)    throws Exception { 
        if (System.getSecurityManager() == null) { 
            System.setSecurityManager(new RMISecurityManager()); 
        } 
        HelloImpl h = new HelloImpl(); 
        Naming.rebind("rmi://203.252.134.119:1099/BABO", h); 
        System.out.println("HelloImpl의 객체 h를 BABO이름으로 바인딩");     
    } //end of main 
} //end of HelloRMIServer 

▣ 자바 시스템 차원의 보안 정책 파일 
◈ [JAVA_HOME]\jre\lib\security\java.policy 
◈ 자바 설치 디렉토리의 jre 디렉토리를 확인하시기 바랍니다.


- 원격 클래스 HelloImpl의 객체 h를 만든 후, Naming의 rebind()를 이용해서 RMI Registry에 바인딩시키고 있다.

- 위의 HelloRMIServer를 실행시키면 RMI Registry에 원격객체가 등록된다.

(단, RMI Registry를 실행시킨 후 HelloRMIServer를 실행해야 한다.)


◈ java -Djava.security.policy=rmi.policy HelloRMIServer 


start rmiregistry(포트 변경 할시 start rmiregistry 2000) - 디폴트 1099번

- 여기서 포트를 변경하려면 위의 rebind()메서드에서 사용한 포트도 변경해줘야 한다.

- 클라이언트가 원격객체를 Look Up할때 RMI서버는 원격 참조 객체(stub)의 메모리를 직렬화시켜 클라이언트로 전송한다.

- 이것을 역직렬화 하기 위해서는 원격 참조 객체의 클래스 파일이 필요한데 이것이 stub파일이다.

- 따라서 stub파일은 클라이언트가 다운로드 할 수 있는 곳에 위치 시켜야 하며, 이때 위치는 codebase를 사용하여 지정한다.


5.Look Up


▣ 클라이언트의 룩업과정을 순서 
◈ Lookup 요청 
◈ 직렬화된 Stub 객체 반환 
◈ Stub 파일을 찾기 위해서 codebase 검색 
◈ Stub 클래스 파일 요청 
◈ Stub 클래스 파일 다운로드 
◈ 직렬화된 Stub 객체와 Stub 클래스를 이용해서 역직렬화


- 역직렬화를 마치면 원격 참조 객체가 만들어지며, 이 원격참조객체를 이용해서 클라이언트는 메서드를 호출 할 수 있다. 단 실제 메서드를 호출하기 위해서는 원격참조객체를 인터페이스로 캐스팅 해주어야 한다. (그래서 공개되어야 하는 것이다..)


import java.rmi.*; 
public class HelloRMIClient { 
    public static void main(String[] args)    throws Exception { 
        if (System.getSecurityManager() == null) { 
            System.setSecurityManager(new RMISecurityManager()); 
        } 
        IHello h = (IHello)Naming.lookup("rmi://203.252.134.119:1099/BABO"); 
        String str = h.sayHello("홍길동"); 
        System.out.println(str); 
    } //end of main 
} //end of HelloRMIClient class 

- 원격 인터페이스로 사용 할 클래스 파일 확보

- 원격 클라이언트 프로그램 컴파일

javac HelloRMIClient.java

- 실행

java -Djava.security.policy=rmi.policy -Djava.rmi.server.codebase=http://www.jabook.org/java/rmi/ HelloRMIClient

- 위의 url은 스텁 파일이 있는 url


- 룩업을 과정을 거쳐서 원격 참조 객체를 얻었다면 객체가 로컬에 있는 것처럼 메서드를 호출할 수 있습니다. 메서드를 호출하기 위해서는 서버에서 배포하는 원격 인터페이스를 이용해서 원격 참조 객체를 캐스팅해야만 합니다. 위의 예에서는 룩업과 동시에 원격 인터페이스로 캐스팅하고 있습니다. 

출처 : jabook.org



'Development > Java' 카테고리의 다른 글

자바 데몬(daemon) 만들기  (0) 2012.01.18
Hotspot JVM의 Garbage Collector  (0) 2012.01.18
자바 SimpleDateFormat  (0) 2011.01.24
아스키 코드  (0) 2011.01.11
초보 Java 웹 개발자들을 위한 학습 로드맵  (0) 2010.12.18
Posted by linuxism
,