分佈式系統之間通訊能夠分爲兩種: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);