10. RMI (Remote Method Invocation) - 분 산 시 스 템 - 국립 창원대학교 컴퓨터공학과 이광휘 http://csl.changwon.ac.kr/
RMI란? (1/4) 자바가 제공하는 분산 객체들 간의 메서드의 호출 객체의 공간적인 제약 없이 객체의 메서드를 사용하여 통신 자바 객체들만의 통신 지원 네트워크상에 존재하는 원격지의 객체에 접근 그 객체의 메서드 호출 그 메서드는 매개변수를 가지고 작업을 수행 작업 결과를 반환
RMI란? (2/4) 분산 객체 모델 클라이언트/서버 모델에서 발전된 통신 모델 자신이 클라이언트이면서 동시에 다른 객체의 서버로 사용 양방향성인 클라이언트 클라이언트/서버 모델을 쉽게 구현 클라이언트와 서버를 객체 단위로 구현 미들웨어(CORBA)를 통해 편리한 서비스를 제공 받음
RMI란? (3/4) 분산 객체 모델과 일반 자바 플랫폼의 공통점 원격 객체의 메서드 호출 시 매개변수나 메서드의 결과값을 객체로 사용 가능 객체 모델에서의 형변환(casting) 연산자 분산 객체 모델에서도 그대로 사용 가능 객체 모델에서의 instanceof 연산자
RMI란? (4/4) 분산 객체 모델과 일반 자바 플랫폼의 차이점 원격 객체의 메서드 호출 시 매개변수나 메서드의 결과값으로 사용되는 객체는 본래 객체의 사본 원격 개체의 경우는 복사본이 아님 몇 개의 메서드들의 제한 java.lang.Object 클래스에서 JVM(Java Virtual Machine)과 관련 있는 일부 메서드 클라이언트 추가적으로, RMI 사용 중 발생 가능성이 있는 예외 처리
RMI 작동 원리 (1/14) 객체 참조자를 통한 메서드 호출 Calculator 참조자 calc.add(10, 5); Client calc.add(10, 5); clac 참조자 Int add(int a, int b){ … } Calculator
RMI 작동 원리 (2/14) RMI를 사용한 분산 시스템 구조 RMI Server Client client calc Calculator Int add(int a, int b){ … } calc.add(10, 5); 원격 참조자 원격 객체 RMI network Reference to
RMI 작동 원리 (3/14) 클라이언트/서버 통신 메커니즘 RMI에서 서버의 역할 원격 객체(Remote Object) 생성 생성된 원격 객체의 참조자(Remote Reference)를 만들어 저장 클라이언트가 서버에 접속 시 원격 참조자 전달 클라이언트가 원격 참조자를 통한 메서드 호출 대기
RMI 작동 원리 (4/14) 클라이언트/서버 통신 메커니즘(계속) RMI에서 클라이언트의 역할 서버에게 사용하려는 메서드를 가진 원격 객체의 참조자 요청 서버로부터 참조자를 넘겨 받음 원격 참조자를 사용하여 메서드 호출
RMI 작동 원리 (5/14) RMI의 기본적인 통신 메커니즘 CLIENT SERVER REMOTE OBJECT (1) 원격 객체 생성 (2) 원격 객체의 참조자 검색요청 (3) 원격 객체의 참조자 반환 (4) 메서드 호출
RMI 작동 원리 (6/14) 원격 참조자를 ‘ro1’이라는 이름으로 RMI Registry에 저장 CLIENT SERVER REMOTE OBJECT ro1 REFERENCE 로컬상에서 일어나는 일 네트워크상에서 일어나는 일 RMI Registry (1) 원격 객체 생성 (5) 메서드 호출 (3) ‘ro1’이라는 이름으로 원격 참조자 검색 요청 (2) ‘ro1’이라는 이름으로 원격 참조자를 저장 (4) 원격 객체의 참조자 반환
RMI 작동 원리 (7/14) Stub/Skeleton을 통한 RMI 통신 메커니즘 Stub과 Skeleton은 미들웨어 생성된 원격 객체를 rmic라는 컴파일러를 통해 만듦 클라이언트와 서버에 위치하여 서로의 통신 과정을 처리
RMI 작동 원리 (8/14) Stub 클라이언트의 메서드 호출을 원격 객체에게 전송 메서드 호출의 매개 변수를 Marshaling 서버로부터 반환된 값을 UnMarshaling 해서 클라이언트에게 전달
RMI 작동 원리 (9/14) Marshaling UnMarshaling 통신 채널로 전송될 수 있는 형태로 바꾸는 것 (바이트 단위) ObjectOutputStream 클래스 사용 UnMarshaling 데이터를 전송 받은 후 원래의 형태로 복원하는 것 ObjectInputStream 클래스 사용
RMI 작동 원리 (10/14) Stub의 메서드 호출 전송을 위한 단계 서버의 자바 가상 머신(JVM)과 연결 설정 전송될 메서드의 매개변수를 특정한 형식에 맞춰 정렬(Marshaling) 전송 원격 메서드의 실행 결과를 기다림 반환값이 전송되어 오면, 이를 읽고 해석(UnMarshaling) 반환값을 호출자에게 반환
RMI 작동 원리 (11/14) Skeleton 클라이언트의 메서드 호출에서 매개변수를 UnMarshaling 해당 원격 객체의 메서드 호출 결과 값을 Marshaling해서 클라이언트에게 전송
RMI 작동 원리 (12/14) Skeleton의 클라이언트 메서드 호출 처리 단계 클라이언트로부터 메서드 호출이 전송되기를 대기 UnMarshaling 매개 변수를 넘겨주고 실행 Marshaling
RMI 작동 원리 (13/14) 원격 메서드 호출 Server Client CLIENT Stub 5 10 2. Marshaling Skeleton 4. UnMarshaling 1. add(5, 10); 3. 전송 REMOTE OBJECT int add(int a, int b) 5. add(5, 10);
RMI 작동 원리 (14/14) 메서드 결과 반환 Server Client CLIENT Stub 15 4. UnMarshaling Skeleton 2. Marshaling 5. 15 반환 3. 전송 REMOTE OBJECT int add(int a, int b) 1. 15 반환
RMI 어플리케이션 예제작성 (1/11) 일반적인 RMI 어플리케이션 구성도 java.rmi.server.RemoteObject java.rmi.server.RemoteServer java.rmi.server.UnicastRemoteObject 클라이언트 프로그램 원격 객체의 메서드를 정의한 인터페이스 실제로 메서드를 구현할 원격 객체 메서드 호출 상속 관계 구현 관계 RMI에서 제공되는 패키지 구현해야 하는 것들
RMI 어플리케이션 예제작성 (2/11) 현금 입출금기를 간단하게 모형화 한 예제 사용자가 현금 입출금기를 통해 서버에 접속 잔액 확인하거나 입금 또는 출금 작업 잔액 확인, 입금, 출금을 요청하는 클라이언트 프로그램 요청을 처리해 주는 서버 프로그램으로 구성
RMI 어플리케이션 예제작성 (3/11) RMI 어플리케이션의 기본적 6단계 과정 1 단계 : 서비스할 원격 객체의 인터페이스 작성 2 단계 : 원격 객체 및 서버 프로그램 작성 3 단계 : Stub / Skeleton 생성 4 단계 : 원격 객체를 사용할 클라이언트 프로그램 작성 5 단계 : RMI Registry 실행 6 단계 : 서버 프로그램과 클라이언트 프로그램 실행
RMI 어플리케이션 예제작성 (4/11) 1 단계 (원격 객체의 인터페이스 작성) java.rmi.Remote 인터페이스 상속 모든 메서드는 public 접근 지정자로 선언 java.rmi.RemoteException을 발생 Bank.java (서버와 클라이언트에서 사용할 인터페이스를 생성한 예제) import java.rmi.*; public interface Bank extends Remote { public int getBalance() throws RemoteException; public int deposit(int amount) throws RemoteException; public int withdraw(int amount) throws RemoteException; }
RMI 어플리케이션 예제작성 (5/11) 2 단계 (원격 객체 및 서버 프로그램 작성) 원격 인터페이스의 메서드들을 구현 java.rmi.server.UnicastRemoteObject 클래스를 상속 RMI Registry에 원격 개체의 참조자를 등록
RMI 어플리케이션 예제작성 (6/11) 2 단계 (원격 객체 및 서버 프로그램 작성) (계속) BankImpl.java (RMI에서의 서버 클래스 예제) import java.rmi.*; import java.rmi.server.*; public class BankImpl extends UnicastRemoteObject implements Bank { private int total; public BankImpl(int total) throws RemoteException { this.total = total; } public int getBalance() throws RemoteException { return total; } public int deposit(int amount) throws RemoteException { total += amount; return getBalance(); } public int withdraw(int amount) throws RemoteException { total -= amount; public static void main(String[] args) throws Exception { BankImpl bankip = new BankImpl(10000); Naming.rebind("//localhost/BankIp", bankip); System.out.println("bank was rebinded with name 'BankIp");
RMI 어플리케이션 예제작성 (7/11) 3 단계 (Stub / Skeleton 생성) rmic 컴파일러를 사용해서 Stub / Skeleton 생성 C:\JavaExample>rmic BankImpl C:\JavaExample>dir ... BankImpl_Skel.class BankImpl_Stub.class
RMI 어플리케이션 예제작성 (8/11) 4 단계 (원격 객체를 사용할 클라이언트 프로그램 작성) 서버의 RMI Registry로부터 원격 참조자 얻어오기 원격 참조자를 통해 메서드 호출하기
RMI 어플리케이션 예제작성 (9/11) 4 단계 (원격 객체를 사용할 클라이언트 프로그램 작성) (계속) BankClient.java (RMI에서의 클라이언트 클래스 예제) import java.rmi.*; public class BankClient { public static void main(String[] args) throws Exception { int balance = 0; Bank bank = (Bank)Naming.lookup("//localhost/BankIp"); System.out.println("Bank was given from Server"); balance = bank.getBalance(); System.out.println("current balance : " + balance); balance = bank.deposit(1000); System.out.println("deposit 1000"); balance = bank.withdraw(5000); System.out.println("withdraw 5000"); }
RMI 어플리케이션 예제작성 (10/11) 5 단계 (RMI Registry 실행) 특정 포트에서 실행 : rmiregistry port번호 C:\JavaExample>rmiregistry 기본 포트인 1099에서 실행 C:\JavaExample>rmiregistry 20000 특정 포트인 20000에서 실행 ▪ Naming.rebind(“//203.246.6.102:20000/Bank”); 서버 프로그램 ▪ Naming.lookup(“//203.246.6.102:20000/Bank”); 클라이언트 프로그램 명시적 기술
RMI 어플리케이션 예제작성 (11/11) 6 단계 (서버 프로그램과 클라이언트 프로그램 실행) C:\JavaExample>java BankImpl bank was rebinded with name ‘Bank’ 서버 프로그램은 RMI Registry가 실행된 서버에서 실행 C:\JavaExample>java BankClinet Bank was given from Server current balance : 10000 deposit 1000 current balance : 11000 withdraw 5000 current balance : 6000
애플릿에서 RMI 사용 (1/3) 애플릿과 서버의 연결 Applet Server Web Browser 네트워크 소켓
애플릿에서 RMI 사용 (2/3) 애플릿에서 RMI를 사용하기 위한 파일 배치 Web Browser Server Applet Web Pages Remote Object Applet Code Stub RMI Registry 등록 애플릿이 로딩된 서버에 있는 RMI Registry에만 연결 가능 로딩
애플릿에서 RMI 사용 (3/3) 애플릿에서 RMI 사용하기 애플릿의 보안상의 제약 때문에 다음은 같은 서버에 존재해야 함 애플릿을 포함하는 웹 페이지들 애플릿 코드 Stub 클래스 원격 객체 RMI Registry
참고 문헌 최영관, 소설같은 자바, JABOOK, 2001년 12월.