Hadoop RPC機制html
RPC:遠程服務調用,底層就是經過網絡實現跨服務的應用調用。WebService是最多見的應用。下圖給RCP的基本原理:基本分爲四層,序列化層、函數調用層、網絡傳輸層、服務端框架層。java
Hadoop的節點之間的通訊、節點之間的心跳等都涉及跨服務應用的調用,也就是常常會運用RCP,因此Hadoop乾脆就開發了一套本身的RCP框架,這Hadoop RCP框架與Alibaba Dubbo來源和使用場景相似(JDK,已經有的RMI的RCP實現爲啥Hadoop和Alibaba又本身開發一套?由於很差用!),常見的RCP框架還有:zero ice、motan(新浪閹割Dubbo版)。Hadoop實現RCP的方式跟WebService不一樣,屬於定製版(核心技術:動態代理、反射、序列化、非阻塞的異步IO:NIO),就是爲了解決hadoop場景下的服務調用。apache
Hadoop RCP的也是至關強大:透明、可控和高性能,Hadoop的具體各層實現:服務器
(1)序列化層:Clent與Server端通訊傳遞的信息採用了Hadoop裏提供的序列化類或自定義的Writable類型;
(2)函數調用層:Hadoop RPC經過動態代理以及java反射實現函數調用;
(3)網絡傳輸層:Hadoop RPC採用了基於TCP/IP的socket機制;
(4)服務器端框架層:RPC Server利用java NIO以及採用了事件驅動的I/O模型,提升RPC Server的併發處理能力;網絡
Hadoop RPC 應用實例:併發
服務端:LoginServiceInterface.javaoracle
public interface LoginServiceInterface { public static final long versionID=1L; public String login(String username,String password); }
應用接口實現類:LoginServiceImpl.java 框架
public class LoginServiceImpl implements LoginServiceInterface { @Override public String login(String username, String password) { return username + " logged in successfully!"; } }
啓動RCP服務端:Starter.java異步
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.RPC.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(); } }
客戶端:服務端一樣實現該接口:LoginServiceInterface.java 該接口的實現類:LoginController.javasocket
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 { //proxy就是上圖中的proxy,利用代理類(實現LoginController和Socket) LoginServiceInterface proxy = RPC.getProxy(LoginServiceInterface.class, 1L, new InetSocketAddress("weekend110", 10000), new Configuration()); String result = proxy.login("mijie", "123456"); System.out.println(result); } }