1.RPC框架的概念

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

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

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

2.RPC框架的原理解析

最近自己写了一个简单的RPC框架KRPC,本文原理分析结合中代码,均为该框架源码 https://github.com/yangzhenkun/krpc

2.1 流程纵览

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

2.2 客户端调用

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

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

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

2.3动态代理

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

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

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

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

2.4网络传输

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

2.5服务端数据接受

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

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

2.6真实调用

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

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

2.7 服务端的动态加载

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

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

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

3.总结

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

https://github.com/yangzhenkun/krpc

这是我最近开始写的一个RPC框架,麻雀虽小五脏俱全,虽然这个框架我还在开发中(还有一些功能没有完成),欢迎一起讨论,star,这个框架中有很多地方可以改进的点。

文章原地址: https://blog.csdn.net/u013592964/article/details/80441205

一篇文章了解RPC框架原理的更多相关文章

  1. 一篇文章让Oracle程序猿学会MySql【未完待续】

    一篇文章让Oracle DB学会MySql[未完待续] 随笔前言: 本篇文章是针对已经能够熟练使用Oracle数据库的DB所写的快速学会MySql,为什么敢这么说,是因为本人认为Oracle在功能性方 ...

  2. 由一篇文章引发的思考——多线程处理大数组

    今天领导给我们发了一篇文章文章,让我们学习一下. 文章链接:TAM - Threaded Array Manipulator 这是codeproject上的一篇文章,花了一番时间阅读了一下.文章主要是 ...

  3. 一篇文章告诉你为何GitHub估值能达20亿美元

    软件开发平台GitHub今日宣布,已获得硅谷多家知名风投2.5亿美元融资,这也让其融资总额达到了3.5亿美元,此轮融资对GitHub的估值约为20亿美元. GitHub有何特别之处? GitHub创立 ...

  4. DEDECMS教程:上/下一篇文章标题长度的截取方法

    对dedecms了解的朋友们,想必对如何获取上一篇.下一篇文章的标签也是非常熟悉.dedecms获取上一篇.下一篇文章的标签分别为:{dede:prenext get='pre'/}.{dede:pr ...

  5. Android:学习AIDL,这一篇文章就够了(下)

    前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...

  6. Android:学习AIDL,这一篇文章就够了(上)

    前言 在决定用这个标题之前甚是忐忑,主要是担心自己对AIDL的理解不够深入,到时候大家看了之后说——你这是什么玩意儿,就这么点东西就敢说够了?简直是坐井观天不知所谓——那样就很尴尬了.不过又转念一想, ...

  7. 一篇文章一张思维导图看懂Android学习最佳路线

    一篇文章一张思维导图看懂Android学习最佳路线 先上一张android开发知识点学习路线图思维导图 Android学习路线从4个阶段来对Android的学习过程做一个全面的分析:Android初级 ...

  8. (转) TensorFlow深度学习,一篇文章就够了

    TensorFlow深度学习,一篇文章就够了 2016/09/22 · IT技术 · TensorFlow, 深度学习 分享到:6   原文出处: 我爱计算机 (@tobe迪豪 )    作者: 陈迪 ...

  9. php下删除一篇文章生成的多个静态页面

    php自定义函数之删除一篇文章生成的多个静态页面,可能有多页的文章,都是需要考虑到的. 复制代码代码如下: //– 删除一篇文章生成的多个静态页面  //– 生成的文章名为 5.html 5_2.ht ...

随机推荐

  1. 阶段3 2.Spring_09.JdbcTemplate的基本使用_4 JdbcTemplate的CRUD操作

    复制demo起名3 保存 update delete selct 有这么多的重载方法 如何去定位 可变参数是JDK1.5版本之后才有的东西 RowMapper 实现RowMapper这个接口.然后实现 ...

  2. python学习之内置函数(一)

    4.7 内置函数 4.7.1 内置函数(1) eval 执行字符串类型的代码,并返回最终结果. eval('2 + 2') # 4 n=81 eval("n + 4") # 85 ...

  3. PEP8-python编码规范(下)

    1.结尾逗号 结尾的逗号通常是可选的,除了在构成一个元素的元组时是强制性需要的(在Python 2 中,它们对 print 语句有语义).为了清晰起见,建议将后者用括号括起来(在技术上是多余的). Y ...

  4. adobe Keychain mac

    Keychain password access This question has been Answered. janec2070563 May 8, 2018 11:07 AM I consta ...

  5. Springg MVC 中文乱码处理

    1.对于post请求的处理方式,在web.xml添加拦截器 <filter> <filter-name>CharacterEncodingFilter</filter-n ...

  6. Spring MVC 中使用AOP 进行事务管理--XML配置实现

    1.今天写一篇使用AOP进行事务管理的示例,关于事务首先需要了解以下几点 (1)事务的特性 原子性(Atomicity):事务是一个原子操作,由一系列动作组成.事务的原子性确保动作要么全部完成,要么完 ...

  7. GITFLOW流程

    GITFLOW流程规范 GIT的使用非常的灵活,但是灵活就导致在使用的过程中有各种各样的情况,根据现有项目组的情况,使用GITFLOW流程规范作为项目开发流程规范. 该规范参考地址: 深入理解学习Gi ...

  8. numpy中的快速的元素级数组函数

    numpy中的快速的元素级数组函数 一元(unary)ufunc 对于数组中的每一个元素,都将元素代入函数,将得到的结果放回到原来的位置 >>> import numpy as np ...

  9. 微信小程序 报错 “对应的服务器无效。控制台输入 showRequestInfo()可以获取更详细信息”

    之前做的项目突然无法读出数据了,一测试发现报这个错误==>对应的服务器无效.控制台输入 showRequestInfo()可以获取更详细信息,后来发现是SSL证书到期了.重新申请了一个证书,免费 ...

  10. bootstrap modal 闪退的办法

     调用: