开发者学堂课程【大数据 ZooKeeper 快速入门: 网络编程:了解 RPC】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/549/detail/7590
网络编程:了解 RPC
目录:
一、什么是 RPC
二、RPC 主要特质
三、RPC 原理
一、什么是 RPC
1.RPC 是一个协议,叫做远程过程调用协议.
2.通俗的描述:客户端程序可以在不知道调用细节的情况下去调用一个存在于另一台机器上的方法或者函数或者过程。在客户端看来就好像在调用本地的一个程序方法一样。
3.正确的描述:是一种通过网络从远程计算机上请求服务,而不需要去了解底层网络技术的一个协议
二、RPC 主要特质
1.RPC 协议:
协议意味着是一个规范,双方按照这个规范去进行通信即可。目前 RBC 协议有很多具体的实现,包括常见的 double、服务管理、访问权限管理等等,这些组件是这个协议的具体。比如 double,叫分布式服务管理,那么它就可以满足在一台机器上去调用一个程序,实际上这个程序,这个服务是存在于另一台机器上,那么在应用程序看来就好像在调用本地程序一样。它就是一个 RPC 的协议实现者,但这些具体的实现者往往都会附加一些其他的功能,这是第一个特质。
2.网络协议和网络 IO 模型对其透明:
不管底层采用的是什么样的网络协议,使用 TCP 还是 udp,还是使用什么样的编程模型,是阻塞还是非阻塞,对于 RPC 的使用者来说根本不用去关心,也就是说底层所有的网络上面的细节对于使用者来说是一个透明的只需要去调用这个程序的时候这个程序呢就可以响应。即使它在另一台机器上,也像是在调用本地的机器一样,因此,网络协议对于 RPC 的客户端来说是透明的,不需要关心它是使用哪一种网络模型。
3.信息格式对齐透明:
在调用方法调用函数的过程中,势必会需要去传递一些参数,参数去执行也会进行一个结果的返回,那么这些参数包括这些结果该以什么样的形式在网络间进行通信?因为它调用的是要调用这个远程在另一台机器上的程序,那么该怎么样去分装,新型格式该怎么压,压缩该怎么去加密,该怎么去加密另一边?该怎么去解密,怎么去解析?这些作为的调用方来说也不需要关心,只知道呢使用这个 RBC。去把这个参数按照格式去使用就可以把结果反馈回来。
4.跨语言能力:
跨语言能力就是对于 RPCB 的使用者、调用方来说,不关心远程提供这个服务的程序是用什么语言编写的。比如在本机想要一个登录用户名和密码验证的功能,那么在另一台机器上它提供了这么一个验证的功能。在 RPC 来看根本不用关心那个提供这个服务的功能,它是用什么语言编写的,是用 Java,还是用 C 语言,还是用其他语言。只要能够满足这边把需要请求发送的参传到那边之后,能够解析把结果反馈回来,针对调用方来说,完全不用担心底层是一个什么样的过程这就是 RPC 的一个本质。可以看到,不管它是怎么去描述,最重要的是 RPC 描述的是这样一个特征,客户端在去调用一个函数或方法的时候,不管它是在远程还是在本地都像是在本地,这就是 RPG 的一个本质。
三、RPC 原理
1.实现一个 RPC,大概需要哪些组件呢?这是一个 IP 的原理图,
图上两个红色的地方,一个是 user,一个是 server,一个是服务的调起方,一个是服务的接收方。比如这里有一个程序要去发起一个函数的调用,调用如果是一个传统的模式,两个程序都在一台程序,一台机器上的话,直接调用本地的即可。但是现在可以发现,调用方在一台机器,接收方在另一台机器。因此,两台机器之间首先需要一RBC的运行实例,也就是说不管是调用方还是被调用方,都需要一个 RPC 的协议。实际上 RPC 在这里完成了一个跨网络通信的功能。
接下来再看图上在不管调用方还是被调用方,还有一个黄色的一个模块存在,左边叫做 user step,另一个叫做 service dep。
steps,叫做存跟。user 这里本地去调用的时候,这个方法目前是不在机器上的,给他一种满足感,让他感觉他在调用本地,给他一个 user steps 存根,就在模拟本地的一个对象,让 user 感觉他是在调用本地,实际上就变成这一种形式:当user发起一个本地调用一个 local 的时候,本地的一个存根他接受到这个请求,接到请求他把这个参数做一个打包,打包交给 RBC 的实例,由他来 RPC 进行一个网络的传输,因此这里可以看到 RBC 它包装了底层的一个通信的协议,通信的模型,是用什么协议来进行传输的,都不需要担心。另一边的 RBC 实例呢,就可以接收到这个请求的封装。
就可以接收到这一个请求的封装。请求封装后,在右边的 server-stub 又有一个存根,因为真正的方法是在 server 里,方法调用又需要一个调用者,这里它就模拟一个 server stable,由他来针对参数做一个 unpack 的一个解析,解析完了之后去调用真正的方法。
比如说从左到右经流程,真正才把调用者和被调用者做了一个连接。调用者他经过了一个参数的解析,如果两边他编程语言是不一样的还要做一个语言的解析。比如这里使用 Java 来进行调用的话,这边 是 c 语言,那么在我 user stub 里要进行一个编码的转换,这个该怎么转换?是要去实现的一个功能。
本地的 server 他会接收到这个请求就开始去工作,有着要去增删改查操作,相关操作,然后把这个结果返回给我们的 user step ,返回之后他还要把结果进行个打包,如果是跨编程语言的话还要针对语言的编码要做一个相关的调整,然后把这个结果发送给服务端的一个运行 RPC 的实例,RPC 成立,再通过他自己之间网络的通信。底层怎么通信的协议不需要去关心,然后交给客户端这边调用方里,然后再把它传给客户,还给在客户端这边的一个存根叫做 user step,由他来针对结果进行一个安排,最后把最终的结果在完成符合这边调用格式的。
经过这么一个从左到右,从右往左的一个过程,是不是就满足了一个本地的一个程序,去调用一个存在于另一台远程机器上的一个方法或者函数,但是在客户端看来是不是就像在调用本地程序。因为发现去调用一个方法,它直接给返回结果,实际上在底层,RPC 协议完成了参数的封装,跨网络协议。一个通信压跨网络的传输以及这边的调用,包括反馈结果的解析。要想去实现开发 RPC 至少要满这么几个部分,这样才可以去沟通或者去开发一个 RPC。