1. 程式人生 > >Java中的RPC分散式範例:RMI

Java中的RPC分散式範例:RMI

什麼是RMI:

       RMI是遠端方法呼叫(Remote Method Invocation)。能夠讓在某個Java虛擬機器上的物件像呼叫本地物件一樣呼叫另一個Java 虛擬機器中的物件上的方法。將網路通訊和併發控制對程式開發人員透明化,那麼將極度簡化此類應用的開發成本,RMI就是這樣一個範例。

優點:

       RMI是Java的一組擁護開發分散式應用程式的API。RMI使用Java語言介面定義了遠端物件,它集合了Java序列化和Java遠端方法協議(Java Remote Method Protocol)。簡單地說,這樣使原先的程式在同一作業系統的方法呼叫,變成了不同作業系統之間程式的方法呼叫,由於J2EE是分散式程式平臺,它以RMI機制實現程式元件在不同作業系統之間的通訊。 RMI大大增強了Java開發分散式應用的能力,是開發百分之百純Java的網路分散式應用系統的核心解決方案之一。其實它可以被看作是RPC的Java版本。但是傳統RPC並不能很好地應用於分散式物件系統。而Java RMI 則支援儲存於不同地址空間的程式級物件之間彼此進行通訊,實現遠端物件之間的無縫遠端呼叫,用RMI開發的應用系統可以部署在任何支援JRE的平臺上。

RMI使用的一般流程:

     1,客戶物件呼叫客戶端輔助物件上的方法;

     2,客戶端輔助物件打包呼叫資訊(變數,方法名),通過網路傳送給服務端輔助物件;

     3,服務端輔助物件將客戶端輔助物件傳送來的資訊解包,找出真正被呼叫的方法以及該方法所在物件;

     4,呼叫真正服務物件上的真正方法,並將結果返回給服務端輔助物件;

     5,服務端輔助物件將結果打包,傳送給客戶端輔助物件;

     6,客戶端輔助物件將返回值解包,返回給客戶物件;

     7,客戶物件獲得返回值。

    對於客戶物件來說,步驟2-6是完全透明的,也就意味著,開發人員無需關注任何的網路資料傳輸處理。

案例:

     服務端及客戶端結構圖

服務端程式碼:

  1. 介面原始檔:

import java.rmi.Remote; import java.rmi.RemoteException; //必須繼承Remote類 public interface IBiz extends Remote {     //方法必須丟擲 RemoteException 異常     public String sayHello(String name) throws RemoteException; }

   2. 介面實現類。

import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject;

import com.icss.service.IBiz; //必須繼承 UnicastRemoteObject類 public class BizImpl extends UnicastRemoteObject implements IBiz {

    public BizImpl() throws RemoteException {         super();     }     //重寫介面方法     @Override     public String sayHello(String name) throws RemoteException {         return "Hello:"+name;     } }

3. 服務端啟動類:

public class Main {     public static void main(String[] args) {         try {             //介面物件建立             IBiz biz = new BizImpl();             //註冊埠             LocateRegistry.createRegistry(10001);             //釋出服務:IP+埠+服務名             Naming.bind("rmi://172.17.4.78:10001/h", biz);         } catch (Exception e) {             System.out.println(e.getMessage());         }     } }

客戶端:

1. 原樣拷貝介面原始檔(包括包路徑)到客戶端,看專案結構圖。

2. 客戶端啟動類:

public class Main {     public static void main(String[] args) {         try {             //根據IP+埠+服務名稱從服務端獲取介面物件             IBiz biz =                       (IBiz) java.rmi.Naming.lookup("rmi://172.17.4.78:10001/h");             //呼叫介面代理物件的方法。             System.out.println(biz.sayHello("張三"));                     } catch (Exception e) {             System.out.println(e.getMessage());         }     } }