给我的小迷妹解释什么是RPC

阅读: 评论:0

给我的小迷妹解释什么是RPC

给我的小迷妹解释什么是RPC

   小迷妹:哥,我问你一个问题啊?

    我:啥问题啊?

   小迷妹:你最近嘴里面天天念叨的rpc 是啥啊?

   我:好,哥今天给你普及一下,什么是rpc。

   小迷妹:哇啊,哥哥你好棒啊。

   我:哈哈,还好还好,你不要这么崇拜我。

 

通俗解释RPC 是什么?

   RPC,就是Remote Procedure Call 远程过程调用 

   小迷妹:啥叫远程过程调用啊,咋搞的那么高深?

   我:我给你举个例子,就是说当你不想下楼吃饭的时候,然后拿起电话,叫了一个外卖,然后外卖小哥就把外卖送过来了,这个就是远程过程调用。

  小迷妹:哥,好像到中午了,刚好我不想下楼,那你帮我远程调用一下把。 

  我:。。。。。

 

精准解释RPC 是什么?

  现如今随着互联网的发展,更多的企业采用了分布式服务,解决了服务单点问题和服务功能一致性问题 ,以应对流量快速的增长。那么分布式服务之间 就会存在调用的问题。

举个例子

 

     

用户模块 是一个服务,交易模块 是一个服务。如果用户服务调用交易服务,因为它是分布到两个服务器上的是跨进程的,所以不能像调用本地方法那样,需要我们做一些处理,这就引入了rpc

来我们画张图

  

1.首先启动交易模块服务,会向外暴漏ip地址和port 端口号。

2.用户模块,通过动态代理,获取到接口和参数。

3.把获取到的接口和参数,以序列化的方式,调用交易模块暴漏出来的ip地址和port  底层通过网络协议,把序列化的数据,传输到交易模块。

4.交易模块,会把客户端传输过来的序列化数据,进行反序列化。

5.反序列化得到的接口和参数,在根据接口名称和参数,反射得到相应的实现类,然后调用实现类最后得到result。

6.最后把result放到数据流中,在根据刚刚建立的长连接,通过网络协议把result返回到客户端。

总结一下,rpc 主要解决以下两点:

  1. 解决分布式系统中,服务之间的调用问题。
  2. 远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑。

 

手写RPC

 流程图

 

rpc-client 客户端

/*** Created by guyan on 2019/9/7 17:21*/
public class RemoteInvokeHandler implements InvocationHandler {private String ip;private int port;public RemoteInvokeHandler(String ip, int port) {this.ip = ip;this.port = port;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("进入代理类");ReqParam param=new ReqParam();param.DeclaringClass().getName());param.Name());param.setParameters(args);System.out.println(&#String() = " + String());return new RpcNetSend(ip,port).send(param);}
}

 

/*** Created by guyan on 2019/9/7 17:23*/
public class RpcNetSend {private String ip;private int port;public RpcNetSend(String ip, int port) {this.ip = ip;this.port = port;}public Object send(ReqParam param) {Socket socket = null;ObjectOutputStream objectOutputStream = null;ObjectInputStream objectInputStream = null;Object result = null;try {socket = new Socket(ip, port);objectOutputStream = new OutputStream());objectOutputStream.writeObject(param);objectOutputStream.flush();objectInputStream = new InputStream());result = adObject();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {try {if (objectInputStream != null) {objectInputStream.close();}if (objectOutputStream != null) {objectOutputStream.close();}} catch (IOException e) {e.printStackTrace();}}return result;}
}
/*** Created by guyan on 2019/9/7 17:14*/
public class RpcProxyClient {public <T> T clientProxy(final Class<T> interfaceClass, String ip, int port) {return (T) ClassLoader(), new Class<?>[] { interfaceClass },new RemoteInvokeHandler(ip, port));}
}
*** Hello world!**/
public class App 
{public static void main( String[] args ){IMsgService iMsgService=new RpcProxyClient().clientProxy(IMsgService.class,"localhost",8080);String result = iMsgService.sayMsg("i am guyan");System.out.println("result = " + result);}
}

rpc-server 服务端:

/*** Created by guyan on 2019/9/7 11:15*/
public interface IMsgService {String sayMsg(String msg);String saveUser(UserDto user);
}
/*** Created by guyan on 2019/9/7 12:24*/
@RpcService(IMsgService.class)
public class IMsgServiceImpl implements IMsgService {@Overridepublic String sayMsg(String msg) {System.out.println("IMsgService.sayMsg the msg is " + msg);return "sayMsg="+msg;}@Overridepublic String saveUser(UserDto user) {System.out.println("IMsgService.saveUser the user is" + user);return "SUCCESS";}
}
/*** Created by guyan on 2019/9/8 15:33*/
public class RpcProxyServer01 implements InitializingBean, ApplicationContextAware {private ExecutorService executorService = wCachedThreadPool();/*** 端口号*/private int port;/*** key:serviceName value:service实例化*/private ConcurrentMap<String,Object> map=new ConcurrentHashMap<>();public RpcProxyServer01(int port) {this.port = port;}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("spring bean 初始化之后");ServerSocket socketServer = null;try {socketServer = new ServerSocket(port);while (true) {Socket accept = socketServer.accept();executorService.submit(new ProcessorHandler(accept, map));}} catch (IOException e) {e.printStackTrace();} finally {if (socketServer != null) {try {socketServer.close();} catch (IOException e) {e.printStackTrace();}}}}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("spring 手动注入!");Map<String, Object> beans = BeansWithAnnotation(RpcService.class);if (beans.isEmpty()){return;}for(Object bean:beans.values()){RpcService rpcService = Class().getAnnotation(RpcService.class);String serviceName = rpcService.value().getName();map.put(serviceName,bean);}}
}
/*** Created by guyan on 2019/9/7 14:03*/
public class ProcessorHandler implements Runnable {private Socket socket;/*** key:serviceName value:service实例化*/private ConcurrentMap<String, Object> map = new ConcurrentHashMap<>();public ProcessorHandler(Socket socket, ConcurrentMap<String, Object> map) {this.socket = socket;this.map = map;}@Overridepublic void run() {System.out.println("进入处理类");ObjectInputStream objectInputStream = null;ObjectOutputStream objectOutputStream = null;try {objectInputStream = new InputStream());ReqParam reqParam = (ReqParam) adObject();Object result = invoke(reqParam, map);objectOutputStream = new OutputStream());objectOutputStream.writeObject(result);objectOutputStream.flush();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {try {if (objectInputStream != null) {objectInputStream.close();}if (objectOutputStream != null) {objectOutputStream.close();}} catch (IOException e) {e.printStackTrace();}}}/*** 通过反射机制找到相应的方法** @param param* @return*/private Object invoke(ReqParam param, ConcurrentMap<String, Object> map) {System.out.println("param = " + param);Object service = (ClassName());if (null == service) {throw new NullPointerException("the service is null,the service name is=[{}]" + ClassName());}Object[] parameters = Parameters(); //获取到参数Class<?>[] types = new Class[parameters.length]; //获取到参数类型for (int i = 0; i < parameters.length; i++) {types[i] = parameters[i].getClass(); //存到class type 数组中}Object result = null;try {Class clazz = Class.ClassName()); //根据类名反射出classMethod method = MethodName(), types); //class 根据方法名和参数获取相应的方法result = method.invoke(service, parameters); //通过传进来的实例类,和参数获取结果} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return result;}
}
*** Hello world!*/
public class App {public static void main(String[] args) {ApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);((AnnotationConfigApplicationContext) applicationContext).start();System.out.println("spring 初始化成功");}
}

 

本文发布于:2024-02-04 00:14:29,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170698337552016.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:小迷妹   RPC
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23