07.远程服务调用
说实话,可能是因为我的理解能力有点小问题,这篇文章读了好几遍才大概明白了点其中的道道。为了防止大家跟我一样学习的时候会晕菜。所以我决定先把作者的行文思路给大家画出来。
- 介绍了下架构师的职责
- RPC在众眼里是什么样的呢?为什么一直这么火呢
- 借用本地调用过程的例子来引入,同时做出假设调用者和被调用者不在同一个进程之内
- 解决上面步骤2问题的方法,有六种。尤其是最后一种本地套接字接口,它的设计理念简直直RPC最初的目的不谋而合
- 但在那个时候对于透明的分布式系统而言,别说存在着大量的问题需要解决的,就连认识上都存在大量误解。
- 最终,施乐公司的Palo Alto研究中心,发布了第一个基于RPC的应用,并正式提出了RPC的概念。
在这篇文章中有几个提法比较有意思:比如RPC作为分布式前置的基础条件,再比如RPC应该是一种高层次的,或者说语言层次的特征,而不是像IPC那样,是低层次的,或者说系统层次的特征;还有RPC以模拟进程间方法调用为起点,许多思想和概念都借鉴的是IPC,都能给人耳目一新的感觉。
好了下面咱们开始正式的内容:
0. 架构师的职责
1 | 什么架构师呢? |
1.大众眼中的RPC(远程服务调用)?
关于RPC三个小问题:
1. RPC本身可以解决什么问题呢
2. 这些问题又是怎么被解决的呢?
3. 为什么要这样解决呀
RPC为什么这么火热的原因:
- 可能是微服务风潮带来的热度
- 作为开发者,我们很多人对RPC本身可以解决什么问题、如何解决这些问题、为什么要这样解决,都或多或少存在些认知模糊的情况
2. 本地方法调用
本地方法调用几个概念
1 | // 调用者(Caller) : main() |
做一个假设:如果在调用println()的时候,发现它并不在当前内存地址空间中,又会出现什么问题呢?
- 前面的传递参数、传回结果都依赖于栈内存的帮助,如果Caller与Callee分属不同的进程,就不会拥有相同的栈内存,那么在Caller进程的内存中将参数压栈,对于Callee进程的执行毫无意义。
- println()方法版本选择依赖于语言规则的定义,而如果Caller与Callee不是同一种语言实现的程序,方法版本选择就将是一项模糊的不可知行为。
如何解决两个进程间通讯的问题问题:
1. 管道(Pipe)或具名管道(Named Pipe): 管道其实类似于两个进程间的桥梁,用于进程间传递少量的字符流或字节流。
2. 信号(Signal): 信号是用来通知目标进程有某种事件发生的。除了用于进程间通信外,信号还可以被进程发送给进程自身。信号的典型应用是kill命令,比如“kill -9 pid”,意思就是由Shell进程向指定PID的进程发送SIGKILL信号。
3. 信号量(Semaphore):信号量是用于两个进程之间同步协作的手段,相当于操作系统提供的一个特殊变量。我们可以在信号量上,进行wait()和notify()操作。
4. 消息队列(Message Queue):进程可以向队列中添加消息,而被赋予读权限的进程则可以从队列中消费消息。消息队列就克服了信号承载信息量少、管道只能用于无格式字节流,以及缓冲区大小受限等缺点 ,但实时性相对受限。
5. 共享内存(Shared Memory): 允许多个进程可以访问同一块内存空间,这是效率最高的进程间通讯形式。进程的内存地址空间是独立隔离的,但操作系统提供了让进程主动创建、映射、分离、控制某一块内存的接口。由于内存是多进程共享的,所以往往会与其它通信机制,如信号量等结合使用,来达到进程间的同步及互斥。
6. <font color="red">本地套接字接口(IPC Socket): 消息队列和共享内存这两种方式,只适合单机多进程间的通讯。而套接字接口,是更为普适的进程间通信机制,可用于不同机器之间的进程通信。</font>
3.竟然不谋而合
RPC可以作为IPC的一种特例来看待。
IPC Socket是操作系统提供的标准接口,所以它完全有可能把远程方法调用的通讯细节,隐藏在操作系统底层,从应用层面上来看,可以做到远程调用与本地方法调用几乎完全一致。
还记得远程服务调用最初的目的吗?与调用本地方法一致。
4.透明RPC调用存在的问题
- 两个进程通讯,谁作为服务端,谁作为客户端?
- 怎样进行异常处理?异常该如何让调用者获知?
- 服务端出现多线程竞争之后怎么办?
- 如何提高网络利用的效率,比如连接是否可被多个请求复用以减少开销?是否支持多播?
- 参数、返回值如何表示?应该有怎样的字节序?
- 如何保证网络的可靠性,比如调用期间某个链接忽然断开了怎么办?
- 服务端发送请求后,收不到回复该怎么办?
分布式运算的八宗罪:
- 网络是可靠的(The network is reliable)
- 延迟是不存在的(Latency is zero )
- 带宽是无限的(Bandwidth is infinite)
- 网络是安全的(The network is secure)
- 拓扑结构是一成不变的(Topology doesn’t change)
- 总会有一个管理员(There is one administrator)
- 不考虑传输成本(Transport cost is zero)
- 网络是同质化的(The network is homogeneous)
5.RPC的概念
传奇的施乐Palo Alto研究中心,发布了基于Cedar语言的RPC框架Lupine,并实现了世界上第一个基于RPC的商业应用Courier。并提出了RPC的概念,也就我们今天看到:
1 | RPC是一种语言级别的通讯协议,它允许运行于一台计算机上的程序以某种管道作为通讯媒介(即某种传输协议的网络),去调用另外一个地址空间(通常为网络上的另外一台计算机) |
思考题
1 | “远程方法不应该无视通讯成本”这个观点,从性能的角度来看是有益的,但从简单的角度看则是有害的。在现代的软件系统开发中,你用过什么RPC框架吗?它们有没有把“像本地方法一样调用远程方法”作为卖点? |