hadoop17---RPC和Socket的区别
RPC是在Socket的基础上实现的,它比socket需要更多的网络和系统资源。RPC(Remote Procedure Call,远程过程调用)是建立在Socket之上的,出于一种类比的愿望,在一台机器上运行的主程序,可以调用另一台机器上准备好的子程序,就像LPC(本地过程调用).
简单RPC之Socket实现
最近看到Dubbo大神写得使用Socket实现的简单的RPC调用,对RPC的理解更简单了,然后根据大神的代码自己也重构了一下。
RPC Server端代码,主要是使用ServerSocket获得rpc调用客户端发送过来的类信息,方法信息及方法参数信息,通过反射在RPCServer端进行代码执行,最后将执行结果发送给Socket,第一步需要首先执行RPCServer。
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.concurrent.ConcurrentHashMap;
- /**
- * 服务端
- * @author tianjunwei
- */
- public class RPCServer {
- public static ConcurrentHashMap<String, Object> classMap = new ConcurrentHashMap<String,Object>();
- public static void main(String [] args) throws Exception{
- System.err.println("server start");
- RPCServer.invoker(8080);
- }
- public static void invoker(int port) throws Exception{
- ServerSocket server = new ServerSocket(port);
- for(;;){
- try{
- final Socket socket = server.accept();
- new Thread(new Runnable() {
- ObjectOutputStream output = null;
- @Override
- public void run() {
- try{
- try {
- output = new ObjectOutputStream(socket.getOutputStream());
- ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
- String className = input.readUTF();
- String methodName = input.readUTF();
- Class<?>[] parameterTypes = (Class<?>[])input.readObject();
- Object[] arguments = (Object[])input.readObject();
- Object claszz = null;
- if(!classMap.containsKey(className)){
- try {
- claszz = Class.forName(className).newInstance();
- classMap.put(className, claszz);
- } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
- e.printStackTrace();
- }
- }else {
- claszz = classMap.get(className);
- }
- Method method = claszz.getClass().getMethod(methodName, parameterTypes);
- Object result = method.invoke(claszz, arguments);
- output.writeObject(result);
- } catch (IOException | ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
- output.writeObject(e);
- }finally {
- output.close();
- }
- }catch(Exception e){
- e.printStackTrace();
- }finally {
- try {
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }).start();
- }catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
RPC 客户端代码,这里利用了代理机制的特性,在执行具体的方法时执行远程调用,执行方法时会调用invoke方法,这样就可以通过Socket向RPCServer发送需要执行的方法的信息,并且获取执行后的结果并返回。
- public class RPCProxy {
- @SuppressWarnings("unchecked")
- public static <T> T create(Object target){
- return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler(){
- @SuppressWarnings("resource")
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- Socket socket = new Socket("localhost", 8080);
- ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
- try {
- output.writeUTF(target.getClass().getName());
- output.writeUTF(method.getName());
- output.writeObject(method.getParameterTypes());
- output.writeObject(args);
- ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
- try {
- Object result = input.readObject();
- if (result instanceof Throwable) {
- throw (Throwable) result;
- }
- return result;
- } finally {
- input.close();
- }
- } finally {
- output.close();
- socket.close();
- }
- }
- });
- }
- }
HelloRpc接口:
- public interface HelloRpc {
- String hello(String name);
- }
HelloRpcImpl实现类:
- public class HelloRpcImpl implements HelloRpc {
- @Override
- public String hello(String name) {
- return "hello "+name;
- }
- }
Main函数操作:
- public class Main {
- public static void main(String [] args){
- HelloRpc helloRpc = new HelloRpcImpl();
- helloRpc = RPCProxy.create(helloRpc);
- System.err.println(helloRpc.hello("rpc"));
- }
- }
执行结果:
hello rpc
通过以上这个示例我们可能会对一些RPC框架的实现原理有一定的了解,比如和我之前发表的Hessian源码分析有一些相似的地方。示例源码地址github,当然这个实现只是作为一些简单的原理说明,还有很多不足的地方。
hadoop17---RPC和Socket的区别的更多相关文章
- RPC和Socket
RPC和Socket的区别 rpc是通过什么实现啊?socket! RPC(Remote Procedure Call,远程过程调用)是建立在Socket之上的,出于一种类比的愿望,在一台机器上运行的 ...
- rpc、socket、mq
关于RPC与MQ异同的理解 相同:1.都利于大型系统的解耦:2.都提供子系统之间的交互,特别是异构子系统(如java\node等不同开发语言):不同:1.RPC侧重功能调用,因此多半是同步的:备注:也 ...
- TCP/IP,HTTP,Socket的区别与联系
一 忆往昔,尽是悔恨泪. 在学校的时候学过,网络七层,也知道tcp的三次握手.但因为根本没用在实际开发中,所以逐渐淡忘.现在就再次理解下三个的区别与联系. 二 正题 网络七层: ...
- Http、tcp、Socket连接区别
转自Http.tcp.Socket连接区别 相信不少初学手机联网开发的朋友都想知道Http与Socket连接究竟有什么区别,希望通过自己的浅显理解能对初学者有所帮助. 1.TCP连接 要想明白Sock ...
- RPC和RMI的区别(Difference Between RPC and RMI)
RPC和RMI的区别(Difference Between RPC and RMI) RPC vs RMI RPC (Remote Procedure Call) and RMI (Remote Me ...
- TCP/IP、Http、Socket的区别与关系
--TCP/IP.Http.Socket的区别与关系 --------------------------------------2014/05/14 网络由下往上分为 物理层.数据链路层.网络层.传 ...
- SOA,Webservice,SOAP,REST,RPC,RMI的区别与联系
SOA,Webservice,SOAP,REST,RPC,RMI的区别与联系 SOA面向服务的软件架构(Service Oriented Architecture) 是一种计算机软件的设计模式,主要应 ...
- RPC与RMI的区别
分布式项目按照以下发展经历了以下技术: CORBA: RMI:基于远程接口的调用 RMI-RROP:这是RMI与CORBA的结合,用在了EJB技术上,EJB留给世界上是优秀的理论和糟糕的架构. WEB ...
- WebSocket和Socket的区别
前段时间写了两篇介绍HTTP和WebSocket的文章,回复中有人说希望了解下WebSocket和Socket的区别.这个问题之前也有想过,自己对此是有大概的答案,可是并不太确定,于是去搜集了些资料( ...
- TCP socket和web socket的区别
小编先习惯性的看了下某中文百科网站对Web Socket的介绍,觉得很囧.如果大家按照这个答案去参加BAT等互联网公司的前端开发面试,估计会被鄙视. 还是让我们阅读一些英文材料吧. 让我们直接看sta ...
随机推荐
- 第一百六十一节,封装库--JavaScript,完整封装库文件
封装库--JavaScript,完整封装库文件 /** *feng_zhuang_ku_1.0版本,js封装库,2016/12/29日:林贵秀 **/ /** 前台调用 * 每次调用$()创建库对象, ...
- 刚新建好的动态网站项目,创建jsp页面就报错
拿到刚刚可以运行的Eclipse,就马上想敲码了,但一创建项目之后再创建jsp页面就报错= =! 报错的内容大概为缺乏对应的jar包. 我们常用Tomcat为中间体,而他本身是带有开发jsp网站的对应 ...
- C#反射Assembly 详细说明,有项目例子
1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等 ...
- bootstrap基础学习十篇
bootstrap字体图标(Glyphicons) a.什么是字体图标 字体图标是在 Web 项目中使用的图标字体.虽然,Glyphicons Halflings 需要商业许可,但是您可以通过基于项目 ...
- 更改Ubuntu的默认开机启动项
终端下: sudo vim /etc/default/grub 修改以下红色语句即可,注意是从0开始: GRUB_DEFAULT=5 #GRUB_HIDDEN_TIMEOUT= GRUB_HIDDEN ...
- Django Admin后台管理模块的使用
Admin后台管理模块的使用 Django的管理员模块是Django的标准库django.contrib的一部分.这个包还包括其它一些实用的模块: django.contrib.auth django ...
- C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西付给另一个类对象,而不是付给引用地址)
from:https://blog.csdn.net/poxiaohai2011/article/details/27555951 //C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西 ...
- sql查询某个字段最长的记录
select `字段`, length(`字段`) from 表名 where length(`字段`) = ( select max(length(`字段`)) from 表名 )
- Segmented 标签栏 切换效果
转载:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0512/1615.html http://www.it165.net/pr ...
- Android 4.4 (KitKat) SMS Apis Change——Android 4.4的一个重大变化
Android团队通过Android开发博客透漏今年会放出Android 4.4 (KitKat) ,同时更新了 SMS 的部分API.博客上讲只有default SMS app才能对短信数据库有写权 ...