一:RPC
RPC 即遠程過程調用(Remote Procedure Call Protocol,簡稱RPC),像調用本地服務(方法)一樣調用服務器的服務(方法)。通常的實現有 XML-RPC , JSON-RPC , 通信方式基本相同, 所不同的只是傳輸數據的格式.
RPC是分布式架構的核心,按響應方式分如下兩種:
同步調用:客戶端調用服務方方法,等待直到服務方返回結果或者超時,再繼續自己的操作
異步調用:客戶端把消息發送給中間件,不再等待服務端返回,直接繼續自己的操作。
同步調用的實現方式有WebService和RMI。Web Service提供的服務是基於web容器的,底層使用http協議,因而適合不同語言異構系統間的調用。RMI實際上是Java語言的RPC實現,允許方法返回 Java 對象以及基本數據類型,適合用於JAVA語言構建的不同系統間的調用。
異步調用的JAVA實現版就是JMS(Java Message Service),目前開源的的JMS中間件有Apache社區的ActiveMQ、Kafka消息中間件,另外有阿里的RocketMQ。
RPC架構里包含如下4個組件:
1、 客戶端(Client):服務調用方
2、 客戶端存根(Client Stub):存放服務端地址信息,將客戶端的請求參數打包成網絡消息,再通過網絡發送給服務方
3、 服務端存根(Server Stub):接受客戶端發送過來的消息並解包,再調用本地服務
4、服務端(Server):真正的服務提供者。
具體實現步驟:
1、 服務調用方(client)(客戶端)以本地調用方式調用服務;
2、 client stub接收到調用后負責將方法、參數等組裝成能夠進行網絡傳輸的消息體;在Java里就是序列化的過程
3、 client stub找到服務地址,並將消息通過網絡發送到服務端;
4、 server stub收到消息后進行解碼,在Java里就是反序列化的過程;
5、 server stub根據解碼結果調用本地的服務;
6、 本地服務執行處理邏輯;
7、 本地服務將結果返回給server stub;
8、 server stub將返回結果打包成消息,Java里的序列化;
9、 server stub將打包后的消息通過網絡並發送至消費方
10、 client stub接收到消息,並進行解碼, Java里的反序列化;
11、 服務調用方(client)得到最終結果。
RPC框架的目標就是把2-10步封裝起來,把調用、編碼/解碼的過程封裝起來,讓用戶像調用本地服務一樣的調用遠程服務。要做到對客戶端(調用方)透明化服務, RPC框架需要考慮解決如下問題:
1、通訊問題 : 主要是通過在客戶端和服務器之間建立TCP連接,遠程過程調用的所有交換的數據都在這個連接里傳輸。連接可以是按需連接,調用結束后就斷掉,也可以是長連接,多個遠程過程調用共享同一個連接。
2、尋址問題 : A服務器上的應用怎么告訴底層的RPC框架,如何連接到B服務器(如主機或IP地址)以及特定的端口,方法的名稱是什么,這樣才能完成調用。比如基於Web服務協議棧的RPC,就要提供一個endpoint URI,或者是從UDDI服務上查找。如果是RMI調用的話,還需要一個RMI Registry來注冊服務的地址。
3、序列化與反序列化 : 當A服務器上的應用發起遠程過程調用時,方法的參數需要通過底層的網絡協議如TCP傳遞到B服務器,由於網絡協議是基於二進制的,內存中的參數的值要序列化成二進制的形式,也就是序列化(Serialize)或編組(marshal),通過尋址和傳輸將序列化的二進制發送給B服務器。
同理,B服務器接收參數要將參數反序列化。B服務器應用調用自己的方法處理后返回的結果也要序列化給A服務器,A服務器接收也要經過反序列化的過程。