1. 程式人生 > >Hadoop中的RPC應用實例

Hadoop中的RPC應用實例

mage 反序列化 網絡 ati final span 同進程 ali ice

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收到請求後,需要對參數進行反序列化(序列化的逆操作),恢復為內存中的表達方式,然後找到對應的方法(尋址的一部分)進行本地調用,然後得到返回值。

一、環境準備:

CentOS 6.9 32位
Linux和Windows版的Eclipse 32位
Hadoop 2.4.1版本
JDK 7+

二、Linux和Windows中的都需要引入Hadoop的Jar包:創建一個 User Libraries,引入

技術分享圖片 技術分享圖片


三、Linux中Eclipse作為服務端

  • 1、創建一個接口LoginServiceInterface.java
package cn.joker.hadoop.rpc;

public interface LoginServiceInterface {

    public static final long versionID=1L;
    
    public String login(String username,String password);
    
}

  • 2、創建一個接口實現類LoginServiceImpl.java
package cn.joker.hadoop.rpc;

public class LoginServiceImpl implements LoginServiceInterface {

    @Override
    public String login(String username, String password) {
        // TODO Auto-generated method stub
        return username + " logged in successfully!";
    }

}

  • 3、創建一個啟動類Starter.java
package cn.joker.hadoop.rpc;

import java.io.IOException;

import org.apache.hadoop.HadoopIllegalArgumentException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.RPC.Builder;
import org.apache.hadoop.ipc.Server;

public class Starter {

    public static void main(String[] args) throws HadoopIllegalArgumentException, IOException {
        
    Builder builder = new RPC.Builder(new Configuration());

    builder.setBindAddress("weekend110").setPort(10000).setProtocol(LoginServiceInterface.class).setInstance(new LoginServiceImpl());
    
    Server server = builder.build();
    
    server.start();
    
    }

}


四、Windows中的Eclipse作為客戶端:

  • 1、創建一個接口LoginServiceInterface.java
package cn.joker.hadoop.rpc;

public interface LoginServiceInterface {
    
    public static final long versionID=1L;
    
    public String login(String username,String password);

}

  • 2、創建一個控制類LoginController.java
package cn.joker.hadoop.rpc;

import java.net.InetSocketAddress;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;

public class LoginController {

    public static void main(String[] args) throws Exception {
        LoginServiceInterface proxy = RPC.getProxy(LoginServiceInterface.class, 1L, new InetSocketAddress("weekend110", 10000), new Configuration());
        
        String result = proxy.login("kevintan", "abc1234");
        
        System.out.println(result);
    }
    
    
}


五、運行Linux端的服務,再運行Windows端的請求,即可完成一個簡單的RPC應用。

技術分享圖片

Hadoop中的RPC應用實例