java分布式实现方式:
- CORBA (没接触过,暂且略过)
- WebService
- RMI远程方法调用
对于WebService,写过接口的人都很熟悉,所以本文重点记录一下RMI。
1.RMI结构图
----图片改编自《JAVA核心技术卷2》
2.示例代码
- 首先定义一个接口,RMI接口要继承Remote类,方法要抛出RemoteException异常,此接口client端也要持有,才能调用远程方法。
import java.rmi.Remote; import java.rmi.RemoteException; public interface IHelloService extends Remote { public void sayHello() throws RemoteException; }
- server端接口实现
import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class HelloServiceImpl extends UnicastRemoteObject implements IHelloService { @Override public void sayHello() throws RemoteException{ System.out.println("Hello World!"); } }
- 注册服务
public class TestServer { public static void main(String args[]) { try { IHelloService service = new HelloServiceImpl(); LocateRegistry.createRegistry(1099); Naming.bind("rmi://localhost:1099/HelloService",Service); } catch (Exception e) { e.printStackTrace(); } } }
- client端调用
public class TestClient { public static void main(String[] args) { try { String url="rmi://localhost:1099/HelloService"; IHelloService service = (IHelloService)Naming.lookup(url); service.sayHello(); } catch (Exception e) { e.printStackTrace(); } }}
文件分布情况
server端:
IHelloService.class
HelloServiceImpl.class
TestServer.class
client端:
IHelloService.class
TestClient.class
RMI虚拟机之间传值的两种机制
(1)继承了Remote类的对象作为远程引用传递
(2)实现了Serializable接口的对象使用序列化进行复制
3.题外话
通过上述示例,一个简单的RMI程序就完成了。但是在实际应用中,会涉及到众多服务的分布式部署,就涉及到多台服务的服务注册问题,书中提到”为了安全原因,注册表只允许来自本机的服务注册“,这就要求注册表服务器里需要有所有发布服务的class文件,个人认为这么做反而比较繁琐了。
此处便引出了另一种架构,各个服务在自己的服务器注册表中注册,由一个中间件去记录服务和地址的映射,客户端通过中间件获取服务地址,达到远程调用的目的。至于提供地址映射的中间件可选方式就很多啦,例如 ZooKeeper 、 Redis等等,甚至你可以自己去实现功能去实现服务和地址映射关系的记录。
本文只谈到了RMI的基本应用,对于书中提到动态加载、远程对象激活等内容暂且忽略,有应用需求的话可以深入了解一下。