RMI
和JNDI
是分布式处理的基础,RMI
远程方法调用,负责分布式方法调用;JNDI
java命名和目录接口,用于更方便查找本地和远程对象
RMI概述
- RMI(Remote Method Invocation) 远程方法调用,是一种计算机直接对象互相调用对方函数,启动对方进程的机制。
- 通过RMI,调用其它计算机上的方法用到的语法和规则和本地对象间调用一样
- 分布式计算,利用多个系统的组合算力,或者多端公用一个中央资源时用到(云计算时代,设备的算力可以向电一样统计和出售)
- 分布式对象编程,通过
RMI
远程调用可以忽略通讯方面的细节
- 服务器程序:创建多个远程对象,并使对象可以被引用。等待客户端调用
- 客户端程序:从服务端程序中的到一个或多个远程对象的引用
- 对等计算程序:双方互为对方的服务器和客户端
创建RMI程序
- 定义远程接口
利用远程接口调用方法,隐藏基类实施细节(接口实现java.rmi.Remote
,方法抛出java.rmi.RemoteException
)
import java.rmi.*;
public interface RmiSample extends Remote{
public int sum(int a,int b) throws RemoteException;
}
- 实现远程接口
- 必须继承
java.rmi.UnicastRemoteObject
,并实现远程接口
- 可以添加其它方法,但是客户端只能调用接口有的方法
import java.rmi.*;
import java.rmi.server.*;
import com.itjob.RmiSample ;
/**
远程接口实现类,继承了UnicastRemoteObject并实现了RmiSample远程接口
*/
public class RmiSampleImpl extends UnicastRemoteObject implements RmiSample{
//覆盖默认构造函数并抛出RemoteException
public RmiSampleImpl() throws RemoteException{
super();
}
//所有远程实现方法必须抛出RemoteException
public int sum(int a,int b) throws RemoteException{
return a+b;
}
}
- 编写服务器类
public class RegistryService {
public static void main(String[] args) {
try {
// 本地主机上的远程对象注册表Registry的实例,默认端口1099
Registry registry = LocateRegistry.createRegistry(1099);
// 创建一个远程对象
HelloRegistryFacade hello = new HelloRegistryFacadeImpl();
// 把远程对象注册到RMI注册服务器上,并命名为HelloRegistry
registry.rebind("HelloRegistry", hello);
System.out.println("======= 启动RMI服务成功! =======");
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
public class NamingService {
public static void main(String[] args) {
try {
// 本地主机上的远程对象注册表Registry的实例
LocateRegistry.createRegistry(1100);
// 创建一个远程对象
HelloNamingFacade hello = new HelloNamingFacadeImpl();
// 把远程对象注册到RMI注册服务器上,并命名为Hello
//绑定的URL标准格式为:rmi://host:port/name
Naming.bind("rmi://localhost:1100/HelloNaming", hello);
System.out.println("======= 启动RMI服务成功! =======");
} catch (RemoteException | MalformedURLException | AlreadyBoundException e) {
e.printStackTrace();
}
}
}
- 编写使用远程服务的客户机类
public class RegistryClient {
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.getRegistry(1099);
HelloRegistryFacade hello = (HelloRegistryFacade) registry.lookup("HelloRegistry");
String response = hello.helloWorld("ZhenJin");
System.out.println("=======> " + response + " <=======");
} catch (NotBoundException | RemoteException e) {
e.printStackTrace();
}
}
}
跟和干
-
stub
客户端辅助对象
-
skeleton
服务端辅助对象
具体作用
- 客户端对象调用服务端辅助对象上的方法
- 服务端福追寻将客户端辅助对象发来的信息解包,找出需要被调用的方法所在对象
- 调用对象方法,返回给服务端辅助对象
- 服务端辅助对象将结果打包,发给客户端辅助对象
- 客户端辅助对象将返回值解包,返回给客户对象
RMI和RPC
区别点 |
RMI |
RPC |
适用语言 |
java |
网络服务协议,和语言无关。通用 |
调用形式 |
通过客户端的Stub 对象作为远程接口进行远程方法调用,每个远程方法有方法签名。如果方法签名没有匹配到远程接口(stub)就不能被调用 |
RPC 通过网络服务协议先远程主机发送请求,发送classname.methodname(args) 形式,远程主机就去搜索匹配的类和方法,找到后执行方法,把结果编码并用网络返回 |
返回类型 |
返回对象或者基本数据类型 |
结果是外部数据表示语言(External Data Representation, XDR)表示,抽象了类和数据结构的差异。 |
网友评论