分布式系统之间通讯能够分为两种:java
远程调用方式就是尽量将系统间的调用模拟为系统内的调用,让使用者感受远程调用就像是调用本地接口同样。但远程调用并不能作到彻底透明,由于存在网络问题、超时问题、序列化/反序列化问题等等。服务器
在Java中实现远程调用的技术主要有RMI和WebService两种。网络
RMI(Remote Method Invocation)中,客户端只有服务端提供服务的接口,经过接口实现对远程服务端的调用。并发
远程调用基于网络通讯来实现,RMI也是如此:分布式
RMI要求服务端接口实现Remote接口,接口上每一个方法必须抛出RemoteException.服务端业务类经过实现该接口提供业务功能,而后调用UnicastRemoteObject.exportObject将对象绑定到某端口上,最后将该对象注册到本地LocateRegistry上,此时造成一个字符串对应于对象实例的映射关系。工具
//服务器端对外提供的接口 public interface Business extends Remote{ public String echo(String message) throws RemoteException; } //服务器端实现该接口的类 public class BusinessImpl implements Buniness{ public String echo(String message) throws RemoteException{ ... } } //基于RMI的服务器端 public static void main(String[] args){ int post = 9527; String name = "BusinessDemo"; Business business = new BusinessImpl(); UnicastRemoteObject.exportObject(business, post); Registry registry = LocateRegistry.createRegistry(1099); registry.rebind(name,business); }
客户端首先经过LocateRegistry.getRegistry()来获取Registry对象,而后经过Registrylookup字符串获取要调用的服务器端口的实例对象,最后以接口的方式调用远程对象的方法。post
Registry registry = LocateRegistry.getRegistry("localhost"); String name = "BusinessDemo"; //建立BusinessDemo类的代理类 RemoteException business business = (Business) registry.lookup(name);
WebService是一种跨语言的系统间交互标准。spa
//服务器端对外提供的接口 public interface Business extends Remote{ public String echo(String message) throws RemoteException; } //服务器端实现该接口的类 @WebService(name="Business",serviceName="BusinessService",targetNamespace="http://WebService.chapter1.book/client") @SOAPBinding(style=SOAPBind.Style.RPC) public class BusinessImpl implements Buniness{ public String echo(String message) throws RemoteException{ ... } } //发布WebService的类 public static void main(String[] args){ Endpoint.publish("http://localhost:9527/BusinessService",new BusinessImpl()); System.out.println("Server has beed started"); }
客户端经过JDK bin目录下的wsimport命令来生成服务调用代码Business.java和BusinessService.java,基于这两个代码编写客户端代码:代理
BusinessService businessService = new BusinessService(); Business business = businessService.getBusinessPort(); business.echo(command);