文章目录
- RPC特性
- RPC实现
- RPC交互流程
- RPC交互时序图
- RPC交互流程
RPC(Remote Procedure Call,远程过程调用) 是一种分布式计算的通信协议和编程模型,用于不同计算机或进程之间进行远程通信。它允许一个计算机程序(通常是客户端)调用另一个计算机上的过程(通常是服务器端)并获取结果,就像调用本地过程一样,而无需了解底层网络通信的细节。
RPC特性
- 透明性: RPC 提供了透明性,使远程调用看起来就像是本地函数调用,屏蔽了底层的网络通信细节
- 跨语言支持: RPC 允许不同编程语言编写的程序进行通信。这意味着一个程序可以使用一种编程语言编写,而另一个程序可以使用完全不同的编程语言编写,它们仍然可以通过 RPC 进行通信
- 序列化和反序列化: 在 RPC 中,参数和结果通常需要序列化(将数据转换为字节流)以进行传输,然后在接收端反序列化(将字节流还原为数据对象)
这是因为远程调用通常涉及跨越网络传输数据(跨网络传输会涉及到大端小端转换) - Stub/Proxy 生成: 为了使 RPC 远程调用透明化,通常需要为每个远程服务生成客户端存根(Client Stub)和服务器端存根(Server Stub)。存根用于隐藏底层通信细节,使客户端和服务器可以像调用本地函数一样调用远程过程
- 网络通信: RPC 依赖于底层的网络通信协议,如 TCP/IP 或 HTTP,以实现客户端和服务器之间的通信
- 错误处理: RPC 提供了一种机制来处理远程调用中可能发生的错误,例如网络故障或服务器不可用。通常,RPC 库会提供异常处理或错误代码来处理这些情况
- 性能: RPC 库通常会尽量提供高性能的实现,以确保在远程调用中不会引入显著的延迟
- 安全性: RPC 可以提供身份验证和授权机制,以确保只有授权的客户端可以访问远程服务
RPC实现
如上述概念所说,RPC协议的目的,是远程调用像本地调用一样简单
要想实现上述目标,需要思考以下问题如何解决:
- 客户端如何连接远程服务端?连接的远端的设备的IP和端口号如何确定?
- 如何表示和传输数据?
- 如何确定客户端发送的请求?
- 如何调用指定的目标方法?
上述问题的解决方案,如下所示:
- 服务注册中心
它的主要作用是帮助服务提供者注册其服务,以及帮助服务消费者发现和调用这些服务
- 服务注册: 服务提供者将其可用的服务注册到服务注册中心。注册通常包括服务的名称、网络地址、端口号、协议等信息。服务注册中心会将这些信息记录在其注册表中。
- 服务发现: 服务消费者通过服务注册中心查询可用的服务列表,以便发现并获取服务提供者的信息。这使得服务消费者无需手动配置服务提供者的地址和端口。
- 负载均衡: 一些服务注册中心提供负载均衡功能,以确保服务请求均匀分布到不同的服务提供者上。这有助于提高系统的性能和可用性。
- 服务健康检查: 服务注册中心通常会定期检查注册的服务是否可用。如果服务不可用,注册中心可以将其从服务列表中移除,以避免服务消费者请求到不可用的服务。
- 动态配置: 服务注册中心允许系统管理员或运维人员在运行时添加、更新或删除服务的注册信息,而无需重启系统或服务。
- 服务版本管理: 有些服务注册中心支持服务版本管理,以允许多个版本的服务并存。这对于逐步升级服务或同时支持多个客户端版本非常有用。
- 安全性: 服务注册中心通常提供安全性措施,以确保只有授权的服务提供者可以注册服务,并且只有授权的服务消费者可以发现和调用服务。
- 支持多种协议: 一些服务注册中心支持多种通信协议,包括HTTP、gRPC、ZooKeeper、etcd等,以适应不同的应用场景和技术栈
常见的 RPC 服务注册中心包括:
- ZooKeeper: 一个开源的分布式协调服务,可以用作服务注册中心
- etcd: 一个开源的键值存储系统,也可以用于服务注册和服务发现
- Consul: 一个开源的服务发现和配置管理工具,具有服务注册中心的功能
- Eureka: Netflix开源的服务注册中心,用于基于Spring Cloud的微服务架构
- Nacos: 阿里巴巴开源的服务注册中心和配置管理平台
- 序列化和反序列化
通常涉及跨越网络传输数据,因此需要将数据序列化(将数据转换为字节流)以进行传输,并在接收端反序列化(将字节流还原为数据对象) - 数据传输
客户端将序列化后的请求参数发送到远程服务器。这通常涉及底层的网络通信协议,如TCP/IP或HTTP - 方法映射
在RPC中,服务器端需要确定客户端请求调用的目标方法,并执行它。这通常包括以下步骤:
- 方法映射表: 服务器端维护一个方法映射表,该表将客户端请求中的方法名映射到实际的方法
- 解析请求: 服务器端解析客户端请求,包括请求中的方法名和参数
- 查找目标方法: 服务器端使用方法映射表查找与客户端请求匹配的目标方法
- 调用目标方法: 服务器端调用找到的目标方法,并将请求参数传递给它
- 执行方法: 目标方法执行所需的操作,并生成结
- 返回结果: 服务器端将方法执行的结果作为响应发送回客户端
方法映射通常通过一些服务框架或RPC库提供。例如,gRPC和Apache Thrift提供了工具来生成客户端存根和服务器端存根,其中包含方法映射和序列化/反序列化的逻辑。这使得在RPC中调用方法变得更加容易和透明。
RPC交互流程
RPC交互时序图
RPC交互流程
- 服务端启动后,会主动向服务注册中心注册设备IP、端口号以及提供的服务列表;如果服务列表更新,服务中心会通知客户端,避免客户端调用服务异常
客户端启动后,会向服务注册中心获取服务端地址列表 - 客户端和服务端建立网络连接
- 客户端调用服务
- 客户端代理(stub翻译为存根,但是代理更直观)将目标服务、目标方法、调用方法的参数等信息序列化,最后将数据传输到服务端代理
- 服务端代理将数据进行反序列化,解析目标服务、目标方法及调用参数,调用相关请求
- 服务端处理请求并返回请求结果
- 服务端代理将服务返回结果序列化,将返回结果发送到服务端