分布式计算第四章 RMI
分布式計算第四章 RMI
1.定義
RPC (Remote Procedure Call):遠程方法調用,用于一個進程調用另一個進程中的過程,從而提供了過程的分布能力。
RMI(Remote Method Invocation):遠程方法調用,即在RPC的基礎上有向前邁進了一步,提供分布式對象間的通訊。允許運行在一個java 虛擬機的對象調用運行在另一個java虛擬機上對象的方法。這兩個虛擬機可以是運行在相同計算機上的不同進程中,也可以是運行在網絡上的不同計算機中。
RMI的全稱宗旨就是盡量簡化遠程接口對象的調用。
RMI大大增強了java開發分布式應用的能力,例如可以將計算方法復雜的程序放在其他的服務器上,主服務器只需要去調用,而真正的運算是在其他服務器上進行,最后將運算結果返回給主服務器,這樣就減輕了主服務器的負擔,提高了效率(但是也有其他的開銷)。
2.為什么需要RMI
為了解決日益龐大的計算模型,網絡模型
2.1設計原理
在設計初始階段,我們真正想要的是這樣一種機制,客戶端程序員以常規方式進行方法調用,而無需操心將數據發送到網絡上或者解析響應之類的問題。所以才有了如下的網絡模型:在客戶端為遠程對象安裝一個代理。代理是位于客戶端虛擬機中的一個對象,它對于客戶端程序來說,就像是要訪問的遠程對象一樣。客戶端調用此代理時,只需進行常規的方法調用。而客戶端代理則負責使用網絡協議與服務器進行聯系。
2.2 網絡模型
計算模型
體系結構
底層類
?
2.3工作原理
RMI能讓一個Java程序去調用網絡中另一臺計算機的Java對象的方法,那么調用的效果就像是在本機上調用一樣。通俗的講:A機器上面有一個class,通過遠程調用,B機器調用這個class 中的方法。
? RMI,遠程方法調用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java應用程序的方便途徑。RMI是非常容易使用的,但是它非常的強大。
? RMI的基礎是接口,RMI構架基于一個重要的原理:定義接口和定義接口的具體實現是分開的。下面我們通過具體的例子,建立一個簡單的遠程計算服務和使用它的客戶程序
1、存根:當客戶端要調用遠程對象的一個方法時,實際上調用的是代理對象上的一個普通方法,我們稱此代理對象為存根(stub)。存根位于客戶端機器上,而非服務器上。
2、參數編組:存根會將遠程方法所需的參數打包成一組字節,對參數編碼的過程就稱為參數編組。參數編組的目的是將參數轉換成適合在虛擬機之間進行傳遞的格式,在RMI協議中,對象是使用序列化機制進行編碼的。
2.4 RMI用途
RMI的用途是為分布式Java應用程序之間的遠程通信提供服務,提供分布式服務。
? 目前主要應用時封裝在各個J2EE項目框架中,例如Spring,EJB(Spring和EJB均封裝了RMI技術)
? 在Spring中實現RMI:
? ①在服務器端定義服務的接口,定義特定的類實現這些接口;
? ②在服務器端使用org.springframework.remoting.rmi.RmiServiceExporter類來注冊服務;
? ③在客戶端使用org.springframework.remoting.rmi.RmiProxyFactoryBean來實現遠程服務的代理功能;
? ④在客戶端定義訪問與服務器端服務接口相同的類
2.5 局限性
RMI目前使用Java遠程消息交換協議JRMP(Java Remote Messaging Protocol)進行通信。JRMP是專為Java的遠程對象制定的協議,由于JRMP是專為Java對象制定的,因此,RMI對于用非Java語言開發的應用系統的支持不足。不能與用非Java語言書寫的對象進行通信(意思是只支持客戶端和服務器端都是Java程序的代碼的遠程調用)。
3.代碼步驟
3.1遠程接口
package cn.com.tt.rmiserver.stub; ? import java.rmi.Remote; import java.rmi.RemoteException; ? import cn.com.tt.rmiserver.bean.Account; ? public interface UserManagerInterface extends Remote{public String getUserName() throws RemoteException;public Account getAdminAccount() throws RemoteException; }3.2接口實現類
?
package cn.com.tt.rmiserver; ? import java.rmi.RemoteException; ? import cn.com.tt.rmiserver.stub.UserManagerInterface; import cn.com.tt.rmiserver.bean.Account; ? public class UserManagerImp implements UserManagerInterface {public UserManagerImp() throws RemoteException { ?}private static final long serialVersionUID = -3111492742628447261L; ?public String getUserName() throws RemoteException{return "TT";}public Account getAdminAccount() throws RemoteException{Account account=new Account();account.setUsername("TT");account.setPassword("123456");return account;} }3.3 實體類
package cn.com.tt.rmiserver.bean; ? import java.io.Serializable; ? public class Account implements Serializable,Cloneable{private static final long serialVersionUID = -1858518369668584532L;private String username;private String password;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;} }?
3.3服務器類
package cn.com.tt.rmiserver.entry; ? import java.rmi.AlreadyBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; ? import cn.com.tt.rmiserver.UserManagerImp; import cn.com.tt.rmiserver.stub.UserManagerInterface; ? public class Entry {public static void main(String []args) throws AlreadyBoundException, RemoteException{UserManagerImp userManager=new UserManagerImp();UserManagerInterface userManagerI=(UserManagerInterface)UnicastRemoteObject.exportObject(userManager,0);// Bind the remote object's stub in the registryRegistry registry = LocateRegistry.createRegistry(2002);registry.rebind("userManager", userManagerI);System.out.println("server is ready");} }?
3.4客戶端類。
新建一個java Project,編寫客戶端代碼。
把Server端的Account類和接口UserManagerInterface,引用到新建的項目中。
?
總結
以上是生活随笔為你收集整理的分布式计算第四章 RMI的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java架构师眼中的高并发架构
- 下一篇: UML建模—EA创建Class(类图)