您的位置:首頁>正文

Hadoop之RPC簡單使用

一、RPC概述

RPC是指遠端程序呼叫, 也就是說兩台不同的伺服器(不受作業系統限制), 一個應用部署在Linux-A上, 一個應用部署在Windows-B或Linux-B上, 若A想要調用B上的某個方法method, 由於不在一個記憶體空間, 不能直接調用, 需要通過網路來表達調用的語意和傳達調用的參數。

樓主在接觸RPC之前, 用得最多的莫過於WebService。 WebService可以說是在RPC發展的基礎之上。 RPC的協議有很多, 比如最早的CORBA, Java RMI,Web Service等, 又比如現在阿裡巴巴的Dubbo, Apache下的hadoop項目。 該篇樓主主要以hadoop的RPC為例。

hadoop為何要使用RPC?在HDFS中, 我們通過jsp可查看到有DataNode,NameNode,SecondaryNameNode主要進程(樓主只啟動了HDFS), 我們用戶端Client與NameNode通信, NameNode與DataNode的通信, 都是在不同進程間,

不同系統間的通信。

二、RPC流程

通過下圖, 我們簡單分析RPC的執行流程:

首先, 要解決通訊的問題, 主要是通過在Client和Server之間建立TCP連接, 遠端程序呼叫的所有交換的資料都在這個連接裡傳輸。 連接可以是按需連接, 調用結束後就斷掉, 也可以是長連接,

多個遠端程序呼叫共用同一個連接。

第二, 要解決定址的問題, 也就是說, A伺服器上的應用怎麼告訴底層的RPC框架, 如何連接到B伺服器(如主機或IP位址)以及特定的埠, 方法的名稱名稱是什麼, 這樣才能完成調用。

第三, 當Client上的應用發起遠端程序呼叫時, 方法的參數需要通過底層的網路通訊協定如TCP傳遞到Server, 由於網路通訊協定是基於二進位的, 記憶體中的參數的值要序列化成二進位的形式, 也就是序列化(Serialize), 通過定址和傳輸將序列化的二進位發送給B伺服器。

第四, Server收到請求後, 需要對參數進行反序列化(序列化的逆操作), 恢復為記憶體中的表達方式, 然後找到對應的方法(定址的一部分)進行本地調用, 然後得到返回值。

三、hadoop—RPC的簡單使用

定義介面Bizable:

1 package cn.jon.hadoop.rpc; 2 3 public interface MyBizable { 4 long versionID = 123456;//該欄位必須要有, 不然會報java.lang.NoSuchFieldException: versionID異常 5 public String doSomething(String str); 6 }

服務端RPCServer實現MyBizable介面並綁定IP位址及埠號:

package cn.jon.hadoop.rpc; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.ipc.RPC; import org.apache.hadoop.ipc.Server; public class RPCServer implements MyBizable { @Override public String doSomething(String str) { return str; } /** * @param args * @throws Exception * @throws */ public static void main(String[] args) throws Exception { Server server = new RPC.Builder(new Configuration) .setProtocol(MyBizable.class) .setInstance(new RPCServer) .setBindAddress("192.168.8.100") .setPort(8077) .build; server.start; } }

用戶端RPCClient:

package cn.jon.hadoop.rpc; import java.net.InetSocketAddress; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.ipc.RPC; public class RPCClient { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub MyBizable proxy = RPC.getProxy(MyBizable.class, 123456,new InetSocketAddress("192.168.8.100", 8077) , new Configuration); String result = proxy.doSomething("服務端"); System.out.println(result); RPC.stopProxy(proxy); } }

樓主使用Linux作為用戶端, Windows作為服務端, 我們先把寫好的程式打成jar, 上傳到Linux:

然後, 我們在windows端啟動RPCServer:

服務端啟動好後, 我們在Linux中執行RPCClient.jar:

java -jar RPCClient.jar

執行結果可以看到輸出了“服務端”(樓主Linux時間沒有調準確):

下篇樓主將對HDFS原理進行探討, 到時會更加詳細的討論RPC。

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示