一:基本原理 主要是要实现网络之间的通讯,
网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络IO来实现,其中传输协议比较出名的有http、 tcp、udp等等,http、tcp、udp都是在基于Socket概念上为某类应用场景而扩展出的传输协议,网络IO,主要有bio、nio、aio 三种方式,所有的分布式应用通讯都基于这个原理而实现。
二:实践
在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS
既然引入出了这么多技术,那我们就顺道深入挖掘下去,了解每个技术框架背后的东西:
1.首先看RMI
RMI主要包含如下内容:
远程服务的接口定义
·远程服务接口的具体实现 ·桩(Stub)和框架(Skeleton)文件 ·一个运行远程服务的服务器 ·一个RMI命名服务,它允许客户端去发现这个远程服务 ·类文件的提供者(一个HTTP或者FTP服务器) ·一个需要这个远程服务的客户端程序 来看下基于RMI的一次完整的远程通信过程的原理:
1)客户端发起请求,请求转交至RMI客户端的stub类;
2)stub类将请求的接口、方法、参数等信息进行序列化;
3)基于tcp/ip将序列化后的流传输至服务器端;
4)服务器端接收到流后转发至相应的skelton类;
5)skelton类将请求的信息反序列化后调用实际的处理类;
6)处理类处理完毕后将结果返回给skelton类;
7)Skelton类将结果序列化,通过tcp/ip将流传送给客户端的stub;
8)stub在接收到流后反序列化,将反序列化后的Java Object返回给调用者。
RMI应用级协议内容:
基于Java串行化机制将请求的java object信息转化为流。
根据采用的协议启动相应的监听端口,当有流进入后基于Java串行化机制将流进行反序列化,并根据RMI协议获取到相应的处理对象信息,进行调用并处理,处理完毕后的结果同样基于java串行化机制进行返回。
tcp/ip。
原理讲了,开始实践:
创建RMI程序的6个步骤:
1、定义一个远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常。
2、定义一个实现该接口的类。
3、使用RMIC程序生成远程实现所需的残根和框架。
4、创建一个服务器,用于发布2中写好的类。
5. 创建一个客户程序进行RMI调用。
6、启动rmiRegistry并运行自己的远程服务器和客户程序
1)首先创建远程接口:
/**
* 远程接口
*
* @author mike
*
* @since 2012-3-14
*/
public interface Hello extends Remote {
/**
* 测试rmi
*
* @return hello
* @throws RemoteException
*/
public String hello()throws RemoteException;
}
2)创建接口实现
package com.gewara.rmi;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
* 远程接口实现
*
* @author mike
*
* @since 2012-3-14
*/
public class HelloImpl extends UnicastRemoteObject implements Hello {
/**
* seria id
*/
private static final long serialVersionUID = -7931720891757437009L;
protected HelloImpl() throws RemoteException {
super();
}
/**
* hello实现
*
* @return hello world
* @throws RemoteException
*/
public String hello() throws RemoteException {
return "hello world";
}
}
3)创建服务器端
package com.gewara.rmi;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
public class Server {
private static final String RMI_URL="rmi://192.168.2.89:10009/server";
/**
* RMI Server
*/
public Server() {
try {
//创建远程对象
Hello hello=new HelloImpl();
//启动注册表
LocateRegistry.createRegistry(10009);
//将名称绑定到对象
Naming.bind(RMI_URL, hello);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
new Server();
}
}
4)创建客服端
package com.gewara.rmi;
import java.rmi.Naming;
public class Client {
private static final String RMI_URL="rmi://192.168.2.89:10009/server";
/**
* @param args
*/
public static void main(String[] args) {
try {
String result=((Hello)Naming.lookup(RMI_URL)).hello();
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5)先启动服务器端,然后再启动客户端
显示结果:hello world
由于涉及到的内容比较多,打算每一篇里讲一个远程通讯框架,继续详解RMI
三:详解RMI内部原理
1. RMI基本结构:包含两个独立的程序,服务器和客户端,服务器创建多个远程对象,让远程对象能够被引用,等待客户端调用这些远程对象的方法。客户端从服务器获取到一个或则多个远程对象的引用,然后调用远程对象方法,主要涉及到RMI接口、回调等技术。
2.RMI回调:服务器提供远程对象引用供客户端调用,客户端主动调用服务器,如果服务器主动打算调用客户端,这就叫回调。
3.命名远程对象:客户端通过一个命名或则一个查找服务找到远程服务,远程服务包含Java的命名和查找接口(Java Naming and Directory Interface)JNDI
RMI提供了一种服务:RMI注册rmiregistry,默认端口:1099,主机提供远程服务,接受服务,启动注册服务的命令:start rmiregistry
客户端使用一个静态类Naming到达RMI注册处,通过方法lookup()方法,客户来询问注册。