1. RPC框架的概念

RPC(Remote Procedure Call)–远程过程调用,通过网络通信调用不同的服务,共同支撑一个软件系统,微服务实现的基石技术。使用RPC可以解耦系统,方便维护,同时增加系统处理请求的能力。

上面是一个简单的软件系统结构,我们拆分出来用户系统和订单系统做为服务存在,让不同的站点去调用。

只需要引入各个服务的接口包,在代码中调用RPC服务就跟调用本地方法一样,我刚接触到这种调用方式的时候颇为惊奇,我明明调用的就是java语言方法啊(已java为例,现在RPC框架一般都支持多语言),怎么就调用了远程的服务了呢??

2. RPC框架的原理解析

最近自己写了一个简单的RPC框架KRPC,本文原理分析结合中代码,均为该框架源码

2.1 流程纵览

如上图所示,我将一个RPC调用流程概括为上图中5个流程,左边3个为客户端流程,右边两个为服务端流程。
下面就各流程进行解析

2.2 客户端调用

服务调用方在调用服务时,一般进行相关初始化,通过配置文件/配置中心 获取服务端地址
用户调用:

// 用户服务接口
public interface UserService {public User genericUser(Integer id,String name,Long phone);
}//调用方
//服务初始化
KRPC.init("D:\\krpc\\service\\demo\\conf\\client.xml");
UserService service = ProxyFactory.create(UserService.class, "demo","demoService");
User user = service.genericUser(1, "yasin", 1888888888L);

一开始接触RPC调用方法肯定就有疑惑,它不是一个接口吗,直接调用应该没啥效果啊,我也没有引入实现包。

带着这个疑惑,我们就进入下一个知识点,动态代理

2.3 动态代理

动态代理这东西意如其名,它代理你帮你做事情。
上面我们不说道直接调用一个接口中的方法,并且没有用该接口的实现类调用,那么方法是怎么生效的呢?

可以看到这个用户服务这个service是由ProxyFactory代理工程创造的,在该ProxyFactory#create()方法中就跟一个代理处理器绑定在一起了

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//构造请求requestRequest request = new Request();....return RequestHandler.request(serviceName, request,returnClass);
}

这个类实现了InvocationHandler接口(JDK提供的动态代理技术),每次去调用接口方法,最终都交由该handler进行处理。
这个环节一般会获取方法的一些信息,例如方法名,方法参数类型,方法参数值,返回对象类型。

同时这个环节会提供序列化功能,一般的RPC网络传输使用TCP(哪怕使用HTTP)传输,这里也要将这些参数进行封装成我们定义的数据接口进行传输。

2.4 网络传输

我们通过将方法参数进行处理后,就要使用发起网络请求,使用tcp传输的就利用socket通信进行传输,这一块我开源项目中使用的同步堵塞的方案进行请求,也可以使用一些非堵塞方案进行请求,效率会更高一些。

2.5 服务端数据接受

这一块使用netty,可以快速一个高性能、高可靠的一个服务端。

public class ServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf = (ByteBuf)msg;byte[] bytes = new byte[buf.readableBytes()];buf.readBytes(bytes);byte[] responseBytes = RequestHandler.handler(bytes);ByteBuf resbuf = ctx.alloc().buffer(responseBytes.length);resbuf.writeBytes(responseBytes);ctx.writeAndFlush(resbuf);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}}

上面代码是我项目中使用的服务端代码。关于netty网上学习的资料很多,这里也只是宏观的讲解RPC原理,就不展开。

2.6 真实调用

服务端获取客户端请求的数据后, 调用请求中的方法,方法参数值,通过反射调用真实的方法,获取其返回值,将其序列化封装,通过netty进行数据返回,客户端在接受数据并解析,这就完成了一次rpc请求调用的全过程。

method = clazz.getMethod(request.getMethodName(),requestParamTypes);
method.setAccessible(true);
result = method.invoke(service, requestParmsValues)123

上面代码片段为通过反射调用真实方法

2.7 服务端的动态加载

通过2.2到2.6的说明,一次RPC请求过程大致如此,但是一个RPC框架会有很多细节需要处理。

其实在一次请求调用前,服务端肯定要先启动。

服务端作为一个容器,跟我们熟知的tomcat一样,它可以动态的加载任何项目。所以在服务端启动的时候,必须要进行一个动态加载的过程。在KRPC中,我使用了URLClassLoader动态加载一个指定路径的jar包,任何业务服务的实现所依赖的jar包都可以放入该路径中。

3. 总结

一个RPC框架大致需要动态代理、序列化、网络请求、网络请求接受(netty实现)、动态加载、反射这些知识点。现在开源及各公司自己造的RPC框架层出不穷,唯有掌握原理是一劳永逸的。掌握原理最好的方法莫不是阅读源码,自己动手写是最快的。

七个步骤,带你快速读懂 RPC 框架原理相关推荐

  1. 六大维度层层剖析,一篇文章带你快速读懂信息无障碍

    我的同事和朋友有一部分是视障人士--盲人或者低视力. 这类群体,据中国盲人协会最新统计在中国有1700多万,加上病变.意外.功能性退化,视障人群比例大约是100比1,这个比例其实很高. 我的这些朋友习 ...

  2. 一文带你快速读懂.NET CLI

    dotnet cli是 .Net Core功能中最有用的特性之一.在这篇文章里,我们将介绍几个.Net OSS工具是如何使用dotnet cli,并介绍如何在日常开发中使用新的cli工具. 正文 关键 ...

  3. 如何快速读懂开源代码?

    文章目录 **RUN起来** **调试** **把控关键数据结构和函数** **从小的开始** **关注一个模块** **工具** **一.阅读开源代码存在的一些误区** 二.阅读代码的心态 **三. ...

  4. 快速读懂UML类图,搞懂类之间的6大关系,轻松绘制UML类图

    快速读懂UML类图,搞懂类之间的6大关系,轻松绘制UML类图 前言 一.UML类图简介 二.类之间的六大关系及UML类图 1.依赖关系及UML类图表示 2.泛化关系及UML类图表示 3.实现关系及UM ...

  5. html语言代码大全,菜鸟快速读懂HTML语言_html

    html语言是网页制作的基础,是初学者必学的内容.虽然现在有许多所见即所得的网页制作工具,但是说到底,还是有必要了解一些HTML的语法.这样,您可以更精确的控制页面的排版,可以实现更多的功能.HTML ...

  6. 网络编程懒人入门(十二):快速读懂Http/3协议,一篇就够!

    本文中文译文由作者"ably.io"发布于公众号"高可用架构",译文原题:<深入解读HTTP3的原理及应用>.英文原题:<HTTP/3 dee ...

  7. 23、90秒快速“读懂”STP(生成树)工作原理

    23.90秒快速"读懂"STP(生成树)工作原理 https://www.toutiao.com/i6794982558787437063/?tt_from=weixin& ...

  8. 快速读懂Http3协议总结

    <网络编程懒人入门(十二):快速读懂Http/3协议,一篇就够!> 什么是 http3 当IETF正式标准化HTTP/2时,Google正在独立构建一个新的传输协议,名为gQUIC.它后来 ...

  9. 网络编程之一泡尿的时间,快速读懂QUIC协议

    网络编程之一泡尿的时间,快速读懂QUIC协议 TCP协议到底怎么了? QUIC协议登场 QUIC协议的目标 QUIC协议这么好,可以大规模切换为QUIC吗? QUIC协议实践 我想试试QUIC协议,可 ...

最新文章

  1. python文件读取输出-Python 读写文件中数据
  2. Extjs4 tab添加右键刷新功能
  3. ElementUI中的el-form怎样格式化显示1和0为是和否
  4. Proxmox VE 安装、配置、使用之第二章 Proxmox VE 的安全性
  5. std::mutex详解
  6. iOS基础 - 控制器
  7. 电脑的基本按键功能有哪些?
  8. Python反向列表
  9. jquery.serialize
  10. numpy数组及处理:效率对比
  11. 天正双击墙体不能编辑_天正CAD绘图必须要知道的技巧
  12. foxmai邮件服务器pop,常见pop和stmp服务器地址-foxmail6或outlook邮件管理
  13. arch配置之百度网盘
  14. Vue 点击文字改变文字颜色
  15. js屏蔽鼠标左右键和键盘按键功能
  16. 今天是大四的第一天,感觉自己特别的慌,在秋招的路上我一个人单枪匹马,在这里我将记录我的历程。
  17. win11记事本出现乱码怎么恢复 windows11记事本出现乱码的解决方法
  18. 论文记录1_YOLO系列(v1 v2 v3 v4)
  19. mysql zimbra_zimbra的使用与管理
  20. MCU开发学习一 地址跳转(自升级的应用)

热门文章

  1. mysql学习【第14篇】:pymysql
  2. 2017年阵亡创业公司圈钱魔咒 烧钱补贴买流量已经过时?
  3. ES6入门概览二--数组
  4. CentOS环境下tomcat启动超级慢的解决方案
  5. 数据库索引的作用和长处缺点
  6. [置顶] HTML5 实现小车动画效果(Canvas/CSS3/JQuery)
  7. fastjson异常问题
  8. 十年,我的计算机生涯
  9. 应用程序虚拟化部署笔记二
  10. Python简介、安装、更新、基本语法及数据类型