RMI虽然不用了,但是它对分布式发展奠定了基础 ,说RMI首先讲是RPC;
什么是RPC : Remote procedure call protocal 远程过程调用协议,客户端在不知道调用细节的情况下,去调用计算机远程的对象的某个方法,这样的一个调用过程就像调用本地方法一样,能够非常方便的进行远程传输,RPC协议其实就是一个规范,包含Dobbo, Thrif,RMI,WebService,Hessain,网络协议和网络IO对于调用端和服务端来说是透明的,也就是说对于我们客户端来说,调用远程方法就跟调用本地方法一样没有任何差异,不需要做任何多的序列化,反序列化操作,选择什么协议,IO模型,RPC对这样的全部过程做了封装;
RMI的概述
RMI(remote method invocation),可以认为是RPC的java版本
RMI使用的是JRMP(Java Remote Messageing Protocol),JRMP是专门为java定制的通信协议,所以它是纯java的分布式解决方案,对于java来说只需要调API即可
如何实现一个RMI程序
1.创建远程接口,并且继承接口java.rmi.Remote接口
2.实现远程接口,并且继承:UnicastRemoteObject
3.创建服务器程序:createRegistry 方法注册成员对象
4.创建客户端程序
如果自己要去实现一个RMI
1.编写服务器程序,暴露一个监听,可以使用socket
2.编写客户端程序,通过ip和端口连接到指定的服务器,并且将数据做封装(序列化)
3.服务器端接收到请求,先反序列化。再进行业务逻辑处理。把返回结果序列化回来
stub是一个动态代理的远程对象
现在RMI不用了,
第一个它是纯java写的,有局限性不能跨语言
第二个服务注册只会注册到RMI registr里面,如果注册中心挂掉之后,注册中心没办法做一个负载,所有的客户中心都不可用了,
第三个它的序列化采用了java原生的序列化,效率低下,而且还没有办法去改变它应为他是jdk里面的;
还有:没有重试机制,服务器底端采用的是BIO而不是NIO性能也不是特别好;
手写一个RMI
User类
public class User{
private int age;
set/get 方法
}
User_Skeleton类
public class User_Skeleton extends Thread{
private UserService userService;
public User_Skeleton(UserService userService){
this.userServer = userService;
}
@Override
public void run(){
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
while(socket!=null){
ObjectInputStream read = new ObjectInputStream(socket.getInputStream());
String method = (String)read.readObject();
if(method.equals("age")){
int age = userServer.getAge();
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeInt(age);
outputStream.flush();
}
}
}catch()finally{if(serverSocket!=null){serverSocket.close()}}
}
}
UserService类
public class UserService extends User{
pubic static void main(String[] args){
UserService userServer=new UserServer();
userService.setAge(18);
User_Skeleton skel = new User_Skeleton(userServer);
skel.start();
}
}
UserClient
public class UserClient{
public static void main(String[] args){
User user = new User_Stub();
System.out.println(user.getAge());
}
}
User_Stub类
public class User_Stub extends User{
private Socket socket;
public User_Stub() throws IOException{
socket = new Socket("localhost",8888);
}
public int getAge() throws IOException{
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeObject("age");
outputStream.flush();
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
return objectInputStream.readInt();
}
}