RPC和Proxy
RPC(Remote Procedure Call):遠程調用過程,調用代碼不在本地執行,實現調用者與被調用者之間的連接和通信。
基於Client Server,相當於DFSClient 相當於客戶端。NameNode集羣相當與Server。
Proxy:代理,是一種設計模式,提供了對目標對象的另一種訪問方式。通過代理對象訪問目標對象。
代理分爲靜態代理和動態代理。
靜態代理:接口的定義,實現接口。被代理對象與對象實現相同的接口。
動態代理:接口的定義不需要實現接口(匿名內部類 + 反射invoke)。
HDFS使用的是動態代理
程序示例
依賴
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.3</version>
</dependency>
接口
package server;
import org.apache.hadoop.ipc.VersionedProtocol;
/**
* 接口
*/
public interface MyInterface extends VersionedProtocol {
/**
* 版本號
*/
static long versionID = 2020;
/**
* 測試方法
* @param param
* @return
*/
String test(String param);
}
package server;
import org.apache.hadoop.ipc.ProtocolSignature;
import java.io.IOException;
/**
* 接口實現類 實際對象
*/
public class MyInterfaceImpl implements MyInterface {
@Override
public String test(String param) {
return "調用test方法:" + param;
}
/**
* 返回版本號
* @param s
* @param l
* @return
* @throws IOException
*/
@Override
public long getProtocolVersion(String s, long l) throws IOException {
return versionID;
}
/**
* 返回簽名信息
* @param s
* @param l
* @param i
* @return
* @throws IOException
*/
@Override
public ProtocolSignature getProtocolSignature(String s, long l, int i) throws IOException {
return new ProtocolSignature(versionID, null);
}
}
RPC服務
package server;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.Server;
import java.io.IOException;
/**
* Hadoop RPC服務
*/
public class MyRPCServer {
public static void main(String[] args) throws IOException {
// 利於Hadoop實現RPC通信
// 1、通過RPC建立通信
RPC.Builder builder = new RPC.Builder(new Configuration());
// 2、定義server參數
builder.setBindAddress("localhost");
builder.setPort(9000);
// 3、部署程序
builder.setProtocol(MyInterface.class);
builder.setInstance(new MyInterfaceImpl());
// 4、開啓server
Server server = builder.build();
server.start();
}
}
RPC客戶端
package client;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import server.MyInterface;
import java.io.IOException;
import java.net.InetSocketAddress;
/**
* 客戶端
*/
public class MyRPCClient {
public static void main(String[] args) throws IOException {
// 使用RPC框架調用server
MyInterface proxy = RPC.getProxy(MyInterface.class,
MyInterface.versionID,
new InetSocketAddress("localhost", 9000),
new Configuration());
System.out.println(proxy.test("hello world"));
}
}