牛逼哄哄的 RPC 框架,底层到底什么原理?
1. RPC框架的概念
RPC(Remote Procedure Call)–远程过程调用,通过网络通信调用不同的服务,共同支撑一个软件系统,微服务实现的基石技术。
使用RPC可以解耦系统,方便维护,同时增加系统处理请求的能力。
上面是一个简单的软件系统结构,我们拆分出来用户系统和订单系统做为服务存在,让不同的站点去调用。
只需要引入各个服务的接口包,在代码中调用RPC服务就跟调用本地方法一样,我刚接触到这种调用方式的时候颇为惊奇,我明明调用的就是java语言方法啊(以java为例,现在RPC框架一般都支持多语言),怎么就调用了远程的服务了呢??
2. RPC框架的原理解析
最近自己写了一个简单的RPC框架KRPC,本文中原理分析结合代码,均为该框架源码,RPC与RMI的区别看这篇文章《Java RMI 和 RPC 的区别》。
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 动态代理
动态代理这东西意如其名,它代理你帮你做事情,动态代理看这篇文章《详解 Java 中的三种代理模式》。
上面我们不说道直接调用一个接口中的方法,并且没有用该接口的实现类调用,那么方法是怎么生效的呢?
可以看到这个用户服务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)
上面代码片段为通过反射调用真实方法
2.7 服务端的动态加载
通过2.2到2.6的说明,一次RPC请求过程大致如此,但是一个RPC框架会有很多细节需要处理。
其实在一次请求调用前,服务端肯定要先启动。
服务端作为一个容器,跟我们熟知的tomcat一样,它可以动态的加载任何项目。所以在服务端启动的时候,必须要进行一个动态加载的过程。
在KRPC中,我使用了URLClassLoader动态加载一个指定路径的jar包,任何业务服务的实现所依赖的jar包都可以放入该路径中。
3. 总结
一个RPC框架大致需要动态代理、序列化、网络请求、网络请求接受(netty实现)、动态加载、反射这些知识点。
现在开源及各公司自己造的RPC框架层出不穷,唯有掌握原理是一劳永逸的。
掌握原理最好的方法莫不是阅读源码,自己动手写是最快的。
牛逼哄哄的 RPC 框架,底层到底什么原理?相关推荐
- 牛逼呀,前端自动化测试框架cypress
自动化测试 为了保障软件质量,并减少重复性的测试工作,自动化测试已经被广泛运用. 自动化测试是一种测试方法,是指使用特定的软件,去控制测试流程,并比较实际结果与预期结果之间的差异.通过将测试自动化, ...
- boot spring 简拼_超牛逼的下拉字典框架,支持拼音简拼搜索,代码项、代码值搜索,无限层级级联,多选、过滤自定义数据表等等...
Dic扩展模块 Dic数据字典模块是v-ci的核心之一,为解决大数据量下拉字典效率及操作问题,特推出通用的数据字典模块,所有字典数据可在数据库维护,在大数据量时采用分页下拉的展示方式,同时支持拼音简拼 ...
- 一文探讨 RPC 框架中的服务线程隔离
Kirito 推荐语:最近秋招开始了,很多学生开始准备起了秋招,有很多人想知道进一些有名的互联网公司实习有什么要求,正好最近跟一位阿里春招的实习小伙子聊了一些 RPC 相关的知识点,于是我把这篇他的思 ...
- 支持多序列化的RPC框架avro-rpc
为什么80%的码农都做不了架构师?>>> avro-rpc http://code.google.com/p/avro-rpc/ 1.开发背景 公司的运营管理平台建立在J2EE ...
- 【分布式服务架构】常用的RPC框架
1. RPC 框架的原理 RPC(Remote Procedure Call,远程服务调用),用来实现部署在不同机器之间系统的方法调用,使程序像当问本地系统资源一样,通过网络传出资源. 1)Clien ...
- java swing 动态生成表格_6 个曾经牛逼哄哄的 Java 技术,你用过吗?
大家好啊,今天给大家分享下我的开发历程中,我知道的那些被淘汰的技术或者框架,有些我甚至都没有用过,但我知道它曾经风光过. 废话不多说,下面我要开始吹了-- 1.Swing 下面这个是用 swing 开 ...
- 牛逼哄哄的全链路监控系统!搭建起来也没有想象中的那么难啊...
点击关注公众号,回复"1024"获取2TB学习资源! 问题背景 随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务.互联网应用构建在不同的软件模块集上 ...
- 牛逼哄哄的SLAM技术 即将颠覆哪些领域?
牛逼哄哄的SLAM技术 即将颠覆哪些领域? 0评论 2016-05-12 21:15:02 来源:雷锋网 作者:宗仁 一般人我不告诉他,绝佳买入机会! 什么是SLAM?机器人在未知环境中,要实现智能化 ...
- 牛逼哄哄的SLAM技术即将颠覆哪些领域
原标题:牛逼哄哄的SLAM技术即将颠覆哪些领域? 什么是SLAM?机器人在未知环境中,要实现智能化需要完成三个任务,第一个是定位(Localization),第二个是建图(Mapping),第三个则是 ...
最新文章
- flask读取数据库(mysql)并展示表格(讲解获取表头的方法)【附上flask好看点的helloworld】
- Theano深度学习入门
- 下列不是c语言浮点常量的是,C语言二级题库.doc
- 火箭轨道计算属于什么计算机技术,2018年计算机二级高级Office每日一练 2月27日...
- 我发现了pandas的黄金搭档!
- Ubuntu下共享目录的设置
- Linux(CentOS)同步时间
- 2020-08-14 光纤通信第三章知识点整理
- Linux常用命令和vi,gdb的使用
- pl/sql developer 安装svn插件 64位
- ​全网首发,TensorFlow 2.0 中文视频教程来啦
- 数据库上云如何顺利进行?6位专家直播助你一臂之力
- (70)信号发生器DDS正弦波设计(二)(第14天)
- MFC开发IM-第十一篇、MFC设置对话框的背景颜色及设置透明
- 黄聪:HBuilder左侧项目管理器如何不与标签页一起自动切换
- 大数据可视化需要遵循哪几个核心原则
- db4o_8.0对象数据库官方文档翻译_学习笔记一
- 微信小程序秀才成语接龙趣味答题小游戏带流量主源码
- 人工智能行业每日必读(2020年1月14日)
- C语言多线程之“哲学家就餐”问题
热门文章
- 锐捷云课堂助力海南农垦中学 根治计算机教室“老病根”
- 32.3. redis-cli - Command-line client to redis-server
- LINUX IP命令详解
- JavaScript 实现数组的foreach
- ClassLoader 初步
- win7下安装rose
- Open Source Bing Maps API for ASP.NET MVC
- matlab 二维线图绘制函数 plot用法参数
- FSM(状态机)、HFSM(分层状态机)、BT(行为树)的区别
- Android NDK开发——Android studio使用JNI调用OpenCV处理图像