在Hadoop中,多个进程(NameNode/DataNode等)之间数据的传递和访问都是通过RPC实现的。RPC是不同进程之间方法调用的解决方案。RPC调用的原理是通过网络代理实现远程方法的调用。这些功能已经被Hadoop封装,直接使用Hadoop提供的类即可以实现RPC远程调用。
由于被调用的类是通过动态代理实现的,所以必须拥有一个接口。且接口上必须拥有一个public static final long versionID=xxxxL的声明,即序列化的versionID字段。
以下简单通过Hadoop RPC代码调用示例,演示RPC在多个进程之间调用的过程。
步骤01 开发一个接口。
在接口中,必须拥有一个versionID唯一的标识当前接口。
【代码3-1】IHello.java
1. package org.hadoop.rpc.service; 2. public interface IHello { 3. //必须声明一个versionID值是任意的Long值 4. long versionID = 937530L; 5. //定义一个方法,用于远程测试调用 6. String say(String name); 7. }
步骤02 开发实现类,并实现接口中的方法。
实现接口,且实现接口中的方法。声明一个类,并声明一个方法,返回一个任意的字符串。一个类如果希望被远程RPC调用,这个类必须实现一个接口,因为内部的原理是JDK动态代理。
【代码3-2】HelloImpl.java
1. package org.hadoop.rpc.service; 2. import java.time.LocalDateTime; 3. public class HelloImpl implements IHello{ 4. @Override 5. public String say(String name) { 6. String str = "Hello "+name+", 当前时间是:"+ LocalDateTime.now(); 7. return str; 8. } 9. }
步骤03 开发服务器。
服务器通过RPC.Builder来创建服务,并通过一个指定的端口对外暴露需要被调用的类。
【代码3-3】RpcServer.java
1. package org.hadoop.rpc.server; 2. public class RpcServer { 3. public static void main(String[] args) throws Exception { 4. System.setProperty("hadoop.home.dir","D:/program/hadoop-3.2.2"); 5. RPC.Server server = new RPC.Builder(new Configuration()) 6. .setProtocol(IHello.class)//设置协议即接口 7. .setInstance(new HelloImpl())//设置实例类 8. .setBindAddress("127.0.0.1")//设置服务器地址 9. .setPort(5678)//设置服务端口 10. .build(); 11. server.start();//启动rpc服务 12. } 13. }
开发完成RpcServer后,右击运行,即可启动RpcServer。启动后,将会占用5678端口,并等待客户端的连接,输出的信息如下所示,即表示启动成功。
Starting Socket Reader #1 for port 5678 IPC Server listener on 5678: starting
步骤04 开发客户端。
使用RPC.getProxy获取本地的一个代理,但是接口类必须与服务器的接口类保持一样,如果调用方是另一个项目,请将接口类复制到调用项目中即可。
【代码3-4】RpcClient.java
1. package org.hadoop.rpc.client; 2. public class RpcClient { 3. public static void main(String[] args) throws Exception { 4. System.setProperty("hadoop.home.dir","D:/program/hadoop-3.2.2"); 5. IHello hello = 6. RPC.getProxy(IHello.class,//指定协议或接口 7. 1L,//指定客户端ID,任意Long值 8. new InetSocketAddress("127.0.0.1", 5678), 9. new Configuration()); 10. String str = hello.say("hadoop"); 11. System.out.println("返回的数据是:"+str); 12. } 13. }
最后,请运行上面的程序代码,如果可以正常返回数据,则说明RPC远程调用成功。RPC调用的过程就是通过服务器地址和端口实现远程类方法的调用。