本文来自于Dubbo官网: 浅谈 RPC,转载请保留连接 ;)
近几年随着微服务化项目的崛起,逐渐成为许多公司中大型分布式系统架构的主流方式,而今天所说的 RPC 在这其中扮演着相当重要的角色。随着这段日子公司项目微服务化的演进,发如今平常开发中都在隐式或显式的使用 RPC,一些刚刚接触 RPC 的小伙伴会感受无所适从,而一些入行多年的老手虽然使用 RPC 经验丰富,但有些对其原理也只知其一;不知其二,缺少对原理的深刻理解,每每也会形成开发中的一些误用。html
RPC(Remote Procedure Call)—远程过程调用,它是一种经过网络从远程计算机程序上请求服务,而不须要了解底层网络技术的协议。也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的方法,因为不在一个内存空间,不能直接调用,须要经过网络来表达调用的语义和传达调用的数据。程序员
RPC协议假定某些传输协议的存在,如TCP或UDP,为通讯程序之间携带信息数据。在OSI网络通讯模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。如今业界有不少开源的优秀 RPC 框架,例如 Spring Cloud、Dubbo、Thrift 等。算法
RPC 这个概念术语在上世纪 80 年代由 Bruce Jay Nelson 提出。这里咱们追溯下当初开发 RPC 的原动机是什么?在 Nelson 的论文 "Implementing Remote Procedure Calls" 中他提到了几点:apache
通俗一点说,就是通常程序员对于本地的过程调用很熟悉,那么咱们把 RPC 做成和本地调用彻底相似,那么就更容易被接受,使用起来毫无障碍。Nelson 的论文发表于 30 年前,其观点今天看来确实高瞻远瞩,今天咱们使用的 RPC 框架基本就是按这个目标来实现的。服务器
Nelson 的论文中指出实现 RPC 的程序包括 5 个部分:网络
这里 user 就是 client 端,当 user 想发起一个远程调用时,它实际是经过本地调用 user-stub。user-stub 负责将调用的接口、方法和参数经过约定的协议规范进行编码并经过本地的 RPCRuntime 实例传输到远端的实例。远端 RPCRuntime 实例收到请求后交给 server-stub 进行解码后发起本地端调用,调用结果再返回给 user 端。架构
以上是粗粒度的 RPC 实现概念结构,接下来咱们进一步细化它应该由哪些组件构成,以下图所示。负载均衡
RPC 服务方经过 RpcServer 去导出(export)远程接口方法,而客户方经过 RpcClient 去引入(import)远程接口方法。客户方像调用本地方法同样去调用远程接口方法,RPC 框架提供接口的代理实现,实际的调用将委托给代理RpcProxy 。代理封装调用信息并将调用转交给RpcInvoker 去实际执行。在客户端的RpcInvoker 经过链接器RpcConnector 去维持与服务端的通道RpcChannel,并使用RpcProtocol 执行协议编码(encode)并将编码后的请求消息经过通道发送给服务方。框架
RPC 服务端接收器 RpcAcceptor 接收客户端的调用请求,一样使用RpcProtocol 执行协议解码(decode)。解码后的调用信息传递给RpcProcessor 去控制处理调用过程,最后再委托调用给RpcInvoker 去实际执行并返回调用结果。以下是各个部分的详细职责:异步
1. RpcServer 负责导出(export)远程接口 2. RpcClient 负责导入(import)远程接口的代理实现 3. RpcProxy 远程接口的代理实现 4. RpcInvoker 客户方实现:负责编码调用信息和发送调用请求到服务方并等待调用结果返回 服务方实现:负责调用服务端接口的具体实现并返回调用结果 5. RpcProtocol 负责协议编/解码 6. RpcConnector 负责维持客户方和服务方的链接通道和发送数据到服务方 7. RpcAcceptor 负责接收客户方请求并返回请求结果 8. RpcProcessor 负责在服务方控制调用过程,包括管理调用线程池、超时时间等 9. RpcChannel 数据传输通道
RPC的设计由Client,Client stub,Network ,Server stub,Server构成。 其中Client就是用来调用服务的,Cient stub是用来把调用的方法和参数序列化的(由于要在网络中传输,必需要把对象转变成字节),Network用来传输这些信息到Server stub, Server stub用来把这些信息反序列化的,Server就是服务的提供者,最终调用的就是Server提供的方法。
RPC 调用分如下两种:
异步和同步的区分在因而否等待服务端执行完成并返回结果。
RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制,让使用者没必要显式的区分本地调用和远程调用,在以前给出的一种实现结构,基于 stub 的结构来实现。下面咱们将具体细化 stub 结构的实现。
RPC的目的是让你在本地调用远程的方法,而对你来讲这个调用是透明的,你并不知道这个调用的方法是部署哪里。经过RPC能解耦服务,这才是使用RPC的真正目的。
这篇文章介绍了 RPC 的一些基本原理,相信到这里您已经对 RPC 有了必定理解。其实发现实现一个 RPC 不算难,难的是实现一个高性能高可靠的RPC框架。好比,既然是分布式了,那么一个服务可能有多个实例,你在调用时,要如何获取这些实例的地址呢?这时候就须要一个服务注册中心,好比在Dubbo中,就可使用Zookeeper做为注册中心,在调用时,从Zookeeper获取服务的实例列表,再从中选择一个进行调用。那么选哪一个调用好呢?这时候就须要负载均衡了,因而你又得考虑如何实现复杂均衡,好比Dubbo就提供了好几种负载均衡策略。因此请继续关注个人另外两篇文章RPC与服务化的关系和注册中心,配置中心, 服务发现浅谈,相信会帮助对RPC设计和实现有更多的理解。