分佈式Java--基於遠程調用實現系統間通訊

分佈式系統之間通訊能夠分爲兩種:java

  • 基於消息方式實現系統間通訊
  • 基於遠程調用方式實現系統間通訊

基於遠程調用實現系統間通訊

遠程調用方式就是儘量將系統間的調用模擬爲系統內的調用,讓使用者感受遠程調用就像是調用本地接口同樣。但遠程調用並不能作到徹底透明,由於存在網絡問題、超時問題、序列化/反序列化問題等等。服務器

兩種基於遠程調用實現系統間通訊的方法

在Java中實現遠程調用的技術主要有RMI和WebService兩種。網絡

RMI

RMI(Remote Method Invocation)中,客戶端只有服務端提供服務的接口,經過接口實現對遠程服務端的調用。併發

遠程調用基於網絡通訊來實現,RMI也是如此:分佈式

  • RMI服務端:經過啓動RMI註冊對象在一個端口上監聽對外提供的接口。服務端接收到客戶端請求後,解析其中的對象信息等,而後經過反射來獲取相應的對象和方法來完成功能的調用。最後將結果序列化經過TCP/IP返回給客戶端。
  • RMI客戶端:經過proxy的方式代理了對服務器端口的訪問。RMI客戶端將要訪問的服務器對象等信息封裝成一個對象序列化後經過TCP/IP傳輸到服務端。最後接收服務端返回的數據,反序列化後交給調用發起者。

服務端代碼:

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

WebService是一種跨語言的系統間交互標準。spa

  • 服務端:以HTTP的形式提供服務,該服務採用WSDL描述,這個文件中描述服務所使用的協議,所但願的參數、返回的參數格式等。服務端應將WSDL文件放入HTTP服務器中,並藉助Java輔助工具根據WSDL文件生成客戶端sub代碼。服務器端接收客戶端請求並經過反射調用服務。
  • 客戶端:經過sub代碼將產生的對象請求信息封裝爲標準的SOAP格式數據,併發送請求到服務器端。客戶端和服務端的數據交互格式是SOAP。

服務端代碼:

//服務器端對外提供的接口
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);
相關文章
相關標籤/搜索