RPC框架的核心是什么 小咪咪 2023-10-15 12:59 19阅读 0赞 #### 文章目录 #### * 什么是 RPC * 封装的艺术(如何隐藏底层逻辑) * 协议的实现 * 序列化和反序列化(编解码) * 总结 ## 什么是 RPC ## 首先思考这样一个问题,假设你不知道任何框架,现在有两台机器,每台机器上有一个服务,让你在其中的一个服务中调用另一个服务中的接口,怎么样才能做到呢? RPC 全称为远程过程调用(Remote Procedure Call Protocol),通俗点来说,就是从一台机器通过网络调用到另一台机器的某个方法。 那这样说来的话,通过 Socket 调用另一台机器的 Sokcet 服务也是RPC,通过一些 HTTP 请求工具包调用一个远程 HTTP 接口也是 RPC 了。 最开始的 RPC 定义还有可能是这样的,但是这种方式太底层、太繁琐了。 现在的 RPC 除了要有明显的网络通信特征外,还要具备下面几个特点: 1. 良好的封装:让我们感觉调用远程接口就好像是调用本地方法一样方便,封装底层网络通信的细节,让我们更专注于业务逻辑。 2. 良好的协议设计:数据在调用方和提供方传输,数据组织要遵循约定好的协议格式,比如 HTTP 协议、TCP 协议这种。 3. 高效的序列化和反序列化:远程调用,所以很大一部分开销来自于数据传输,所以原则上数据量越小越好,这就依赖于序列化的算法了。 ## 封装的艺术(如何隐藏底层逻辑) ## 如果每次调用提供方提供的方法时都像下面这样繁琐,指明 URL、自己构造 JSON 序列化字符串等等,会不会不太方便。 public static final MediaType JSON = MediaType.get("application/json; charset=utf-8"); OkHttpClient client = new OkHttpClient(); String post(String url, String json) throws IOException { RequestBody body = RequestBody.create(json, JSON); Request request = new Request.Builder() .url(url) .post(body) .build(); try (Response response = client.newCall(request).execute()) { return response.body().string(); } } 而像 Dubbo 这样调用,如果没有接触过 RPC 的人,刚看到这段代码会感觉到好像就是在调用本地的一个方法。隐藏了很多的细节。 @DubboReference private DemoService demoService; String result = demoService.sayHello("world"); System.out.println("Receive result ======> " + result); 这就是现代 RPC 里一个很重要的特性,就是封装,尽量隐藏网络上的细节,让使用者感觉就是在调用本地的方法。 ![在这里插入图片描述][6b0f69f0dfc94193b69d4f086a27495a.png] 那在一般的 RPC 框架中,例如 Dubbo、GRPC等,是如何进行封装的呢。 我们看上面的图,其中调用方和服务提供方都有一个部分叫做存根(Stub),就是靠的它。听上去感觉这词不太容易理解啊,啥叫存根呢,其实说简单点儿就是一个代理方案。 举个例子,当我们调用本地的一个服务类的某个方法时,实际上这个服务类已经是一个代理类了,调用这个类的某个方法,实际上代理方法中可以加入很多额外的逻辑,比如构造 HTTP 请求、构造TCP 请求等等,最终穿过网络调用到真正的服务提供方的同名方法。 说到 Java 中的代理技术,相信大家都不陌生,有动态代理、静态代理,不了解的同学可以参考 [Spring AOP 和 动态代理技术][Spring AOP _] 这篇文章。 ## 协议的实现 ## 这里说的协议就是网络通信协议。远程过程调用嘛,那必须得通过网络传输才行,而通过网络传输那就得有遵行规定的协议。 这个协议是用来规范传输的数据的,所以它是一个应用层协议,比如 HTTP ,而不是传输层的协议,比如 TCP 、UDP 。 比如 GRPC 框架中用的协议是 HTTP2,Dubbo中可以选择多种协议,比如Hession、HTTP等。 下图是 HTTP 1.0 协议的格式,包括首部和请求内容,首部可以指定请求方式、URI、版本、内容类型和长度等,内容部分就是真正要传输的数据, 如果是一个 RPC 调用的话,那就是调用方法的参数和一些额外的信息(比如调用的方法名、类名等),首部和内容由一个空行分隔。 接收端可以根据空行了解哪些是头部,哪些是内容。 可以通过首部的内容长度字段来进行分配内存或其他操作。 ![在这里插入图片描述][fe611d62ab6348fe9c81059be747530b.png] 其他的协议都有自己的格式,我们也可以自定义一个协议。如下是一个简单的协议格式: 通过魔术位可以直接判断是不是本协议数据,如果是的话,再进行处理。 通过整体长度和首部长度可以确定数据内容的长度,用来解析首部和数据。 通过序列化方式字段可以确定数据序列化采用的什么方式,用来实现反序列化。 <table> <thead> <tr> <th align="left">0-8bit</th> <th align="left">9-24bit</th> <th align="left">25-32bit</th> <th align="left">33-40bit</th> </tr> </thead> <tbody> <tr> <td align="left">不定长标志位(魔术位)</td> <td align="left">整体长度</td> <td align="left">首部长度</td> <td align="left">序列化方式</td> </tr> </tbody> </table> 一个 RPC 框架使用哪种协议是有权衡取舍的,如果考虑通用性那就可能使用 HTTP或者 HTTP2这种协议,比如 GRPC ,这样一来,可以在各种语言框架中通用,但是性能就稍微差一点了。 而如果从性能方面考虑呢,那就要牺牲掉一部分通用性了,比如Hession、Dubbo2协议,只有框架开发者提供了对应语言的版本,才能在相应的语言中使用。 ## 序列化和反序列化(编解码) ## 上面说的协议主要指的是数据通信协议,而序列化和反序列化其实也要遵循一定的协议。 说到序列化和反序列化,其实我们并不陌生。在Java开发中,经常会遇到。最常用的就是把 Java Bean 序列化为 JSON,将 JSON 反序列化为 Java Bean。 JSON 就是最常见的一种序列化和发序列化协议,其他的序列化方式还有 XML、GRPC 中用到的 Protocol Buffers。 Hessian 也有它自己的序列化算法。 为什么要有序列化呢,数据要想在网络中传输,那必须是二进制的形式。在远程调用里,我们像调用本地方法那样调用,使用的参数都是和当前项目语言一致的参数类型,比如Java中的 String、List、Map等等,那要把这些类型转换成二进制,靠的就是序列化算法。 JSON 和 XML 这种文本序列化方式比较简单,使用场景非常广泛,通用性强,但是序列化后产生的二进制体积也比较大,这样在传输的时候就会比较耗时、占用带宽。 而像 Protocol Buffers 这种序列化方式,它使用结构化的消息定义语言(IDL)来定义数据结构和服务接口,支持多种编程语言,而且序列化后的二进制也会最大程度的压缩,少占用带宽,有很高的传输效率。 ## 总结 ## 下图是整个 RPC 调用过程的简化版。 ![在这里插入图片描述][0c50ac557339411cad19747e97005ce4.png] 序列化和反序列化功能会在代理中进行,在很多框架中也称这部分为编解码。 封装的网络请求既有可能是 HTTP 请求,也有可能是 Sockets 请求,比如有很多 RPC 功能都使用 Netty 作为通讯层。 除了主要的功能外,一个成熟的 RPC 框架还有考虑诸多其他因素,比如性能、安全性、兼容性等等。 [6b0f69f0dfc94193b69d4f086a27495a.png]: https://img-blog.csdnimg.cn/6b0f69f0dfc94193b69d4f086a27495a.png [Spring AOP _]: https://writer.blog.csdn.net/article/details/129010718 [fe611d62ab6348fe9c81059be747530b.png]: https://img-blog.csdnimg.cn/fe611d62ab6348fe9c81059be747530b.png [0c50ac557339411cad19747e97005ce4.png]: https://img-blog.csdnimg.cn/0c50ac557339411cad19747e97005ce4.png
相关 RPC框架的核心是什么 文章目录 什么是 RPC 封装的艺术(如何隐藏底层逻辑) 协议的实现 序列化和反序列化(编解码) 总结 什么是 RPC 首先思考这样 小咪咪/ 2023年10月15日 12:59/ 0 赞/ 20 阅读
相关 通俗的解释一下什么是 RPC 框架? 在这篇文章中: RPC 功能目标 RPC 调用分类 RPC 结构拆解 RPC 组件职责 RPC 实现分析 导出 秒速五厘米/ 2023年06月18日 06:58/ 0 赞/ 18 阅读
相关 通俗的解释一下什么是 RPC 框架? 在这篇文章中: RPC 功能目标 RPC 调用分类 RPC 结构拆解 RPC 组件职责 RPC 实现分析 导出 古城微笑少年丶/ 2023年06月18日 06:58/ 0 赞/ 19 阅读
相关 通俗的解释一下什么是 RPC 框架? 在这篇文章中: RPC 功能目标 RPC 调用分类 RPC 结构拆解 RPC 组件职责 RPC 实现分析 导出 古城微笑少年丶/ 2023年06月18日 06:58/ 0 赞/ 26 阅读
相关 什么是RPC RPC Remote Procedure Call,翻译成中文为远程过程调用,它实际上是一种思想,简单说就是本机调用一个函数,但是这个函数是在另一台机器上执行的,这种编码方式就 心已赠人/ 2022年10月15日 14:58/ 0 赞/ 210 阅读
相关 什么是rpc RPC概念及分类 RPC全称为Remote Procedure Call,翻译过来为“远程过程调用”。目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同 悠悠/ 2022年05月23日 06:39/ 0 赞/ 293 阅读
相关 【夯实Dubbo】什么是RPC框架? 本文属于【夯实Dubbo】系列文章,该系列旨在用通俗易懂的语言,带大家了解和学习 Dubbo 技术,希望能给读者带来一些干货。系列目录如下(可能随着写作的进行,会做一些调整): 末蓝、/ 2022年04月25日 10:10/ 0 赞/ 338 阅读
相关 什么是 RPC? RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。比如两个不同的服务A,B部署在两 爱被打了一巴掌/ 2022年04月13日 11:28/ 0 赞/ 291 阅读
相关 什么是RPC 一个阳光明媚的早晨,老婆又在翻看我订阅的技术杂志。 “老公,什么是RPC呀,为什么你们程序员那么多黑话!”,老婆还是一如既往的好奇。 “RPC,就是Remote Proc 朱雀/ 2022年03月22日 11:53/ 0 赞/ 322 阅读
相关 什么是RPC 转载自:[https://www.jianshu.com/p/2accc2840a1b][https_www.jianshu.com_p_2accc2840a1b] 目录 柔光的暖阳◎/ 2022年03月17日 05:44/ 0 赞/ 327 阅读
还没有评论,来说两句吧...