Hadoop RPC机制及实现

版权声明:原创文章,转载请注明出处! https://blog.csdn.net/L_15156024189/article/details/86547642

机制

以后补上

实现

hadoop版本:hadoop-2.7.3

服务端

定义RPC协议接口

package rpc.server;

import org.apache.hadoop.ipc.VersionedProtocol;

/**
 * Created by leboop on 2019/1/18.
 */
public interface MyInterface extends VersionedProtocol {
    //版本号变量名必须是versionID
    long versionID = 1L;

    int add(int a, int b);
}

(1)MyInterface继承Hadoop的VersionedProtocol接口

(2)在MyInterface接口中定义版本号变量versionID,注意变量名必须是versionID,原因是RPC类的getProtocolVersion方法是通过字符串versionID获取版本号的,如下:

static public long getProtocolVersion(Class<?> protocol) {
    if (protocol == null) {
      throw new IllegalArgumentException("Null protocol");
    }
    long version;
    ProtocolInfo anno = protocol.getAnnotation(ProtocolInfo.class);
    if (anno != null) {
      version = anno.protocolVersion();
      if (version != -1)
        return version;
    }
    try {
      Field versionField = protocol.getField("versionID");
      versionField.setAccessible(true);
      return versionField.getLong(protocol);
    } catch (NoSuchFieldException ex) {
      throw new RuntimeException(ex);
    } catch (IllegalAccessException ex) {
      throw new RuntimeException(ex);
    }
  }

(3)在MyInterface中自定义了一个方法,用于计算两个整数的和。

实现RPC协议

package rpc.server;

import org.apache.hadoop.ipc.ProtocolSignature;

import java.io.IOException;

/**
 * Created by leboop on 2019/1/18.
 */
public class MyInterfaceImpl implements MyInterface {
    public int add(int a, int b) {
        System.out.println("*********Server*********");

        return a + b;
    }

    public long getProtocolVersion(String protocol, long clientVersion) throws IOException {
        System.out.println("MyInterface.versionID=" + MyInterface.versionID);
        return MyInterface.versionID;
    }

    public ProtocolSignature getProtocolSignature(String protocol, long clientVersion, int clientMethodsHash) throws IOException {
        return new ProtocolSignature();
    }
}

(1)MyInterfaceImpl实现了MyInterface接口的add()方法,为了待会能够看出RPC服务端的add()方法被调用,打印了一些信息;

(2)MyInterfaceImpl实现了VersionedProtocol接口的getProtocolVersion和getProtocolSignature方法,分别返回协议接口的版本号和协议签名;

 

构造RPC Server端

package rpc.server;

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

import java.io.IOException;

/**
 * Created by leboop on 2019/1/18.
 */
public class ServerMain {
    public static final String IP = "192.168.189.112";
    public static final int PORT = 1234;

    public static void main(String[] args) {
        MyInterfaceImpl proxy = new MyInterfaceImpl();
        RPC.Builder builder = new RPC.Builder(new Configuration());

        builder.setBindAddress(IP);
        builder.setPort(PORT);
        builder.setProtocol(MyInterface.class);
        builder.setInstance(new MyInterfaceImpl());
        Server server = null;
        try {
            server = builder.build();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Server正在运行……");
        server.start();
    }
}

(1)服务端绑定了IP地址和对应的端口号,其中IP地址是部署该服务端程序的Linux的IP地址,可以使用localhost,端口可以任意定义。

(2)通过server.start()启动服务端。

客户端

客户端代码相对比较简单,只有一个主程序,如下:

package rpc.client;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import rpc.server.MyInterface;

import java.io.IOException;
import java.net.InetSocketAddress;

/**
 * Created by leboop on 2019/1/18.
 */
public class MyClient {
    public static final String IP = "192.168.189.112";
    public static final int PORT = 1234;

    public static void main(String[] args) {
        InetSocketAddress inetSocketAddress = new InetSocketAddress(IP, PORT);

        try {
            // 注意:这里传入的版本号需要与代理保持一致
            MyInterface proxy = RPC.waitForProxy(
                    MyInterface.class, MyInterface.versionID, inetSocketAddress,
                    new Configuration());
            int result = proxy.add(10, 25);
            System.out.println("10+25=" + result);

            RPC.stopProxy(proxy);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

(1)注意这里IP地址和端口号必须与服务端设定的一致;

(2)客户端向服务端传递了两个整数:10和25,通过调用服务端的RPC协议接口实现类的add方法计算出他们的和,并将结果返回给客户端。

部署

将服务端代码打成可执行jar包,上传至Linux服务器上,执行

java -jar jar包

启动服务端,如图:

服务端已经启动成功,现在在Windows本地启动客户端,此时会在服务端输出add方法被调用的信息,如图:

同时将计算结果返回给客户端输出,如图:

猜你喜欢

转载自blog.csdn.net/L_15156024189/article/details/86547642