项目提供 RPC 接口和第三方类库方法有什么区别?

目前参与的分布式项目中会写一些 RPC 接口供其他服务调用,但是我发现这些方法也可以以打包部署到远程仓库的方式供给其他服务导入使用,但为什么不使用后者方式呢?

阅读 2k
avatarAI BotBETA

RPC(Remote Procedure Call)方法调用与本地调用的主要差异在于调用发生的位置、网络通信的开销、以及如何处理调用失败和异常。这些差异使得RPC在某些场景下比本地调用更为复杂,但并不意味着RPC不适用于本地调用,而是说在某些情况下使用本地调用可能更为高效。

RPC与本地调用的主要差异:

  1. 位置:本地调用发生在同一进程内,而RPC调用通常发生在不同的进程或不同的机器上。
  2. 网络通信:RPC涉及网络通信,这可能会引入延迟、带宽限制和潜在的失败点(如网络中断)。本地调用则没有这些问题。
  3. 序列化/反序列化:RPC需要将参数和返回值序列化为字节流以便在网络上传输,然后在目标端反序列化。这可能会引入额外的开销和复杂性。本地调用则直接传递内存中的对象,无需序列化和反序列化。
  4. 异常处理:RPC调用失败时,需要一种机制来通知调用方(通常是抛出异常或返回错误代码)。这种机制可能需要额外的协议和复杂性来确保错误信息的准确传递。本地调用则可以直接使用语言的异常处理机制。
  5. 负载均衡和容错:对于RPC,可能需要实现负载均衡和容错机制,以确保服务的高可用性和可扩展性。本地调用则无需考虑这些问题。

为何RPC不适用于本地调用?

实际上,RPC可以用于本地调用,但通常不是最佳选择。原因如下:

  • 性能开销:本地调用通常比RPC调用更快,因为避免了网络通信和序列化/反序列化的开销。
  • 复杂性:引入RPC框架会增加系统的复杂性和维护成本,特别是当只需要本地调用时。
  • 调试难度:RPC调用失败时,调试可能会更加困难,因为需要考虑网络问题和序列化/反序列化错误等因素。
  • 依赖关系:使用RPC框架会增加对外部库的依赖,这可能会增加部署和管理的复杂性。

使用RPC的场景:

  • 分布式系统:当需要在不同的进程或机器上调用方法时,RPC是首选的解决方案。
  • 微服务架构:在微服务架构中,服务之间的通信通常通过RPC实现。
  • 跨语言调用:当需要在不同的编程语言之间调用方法时,RPC提供了一种通用的解决方案。

总结:

RPC和本地调用各有优缺点,适用于不同的场景。在大多数情况下,本地调用是最高效和最简单的选择。然而,在需要跨进程或跨机器通信的场景中,RPC是不可或缺的。选择哪种方式取决于具体的需求和约束条件。

4 个回答

感觉理解不是太到位。

RPC是进程间调用的一种方式,本质是本地程序调用远程计算机上过程/函数的机制。
SDK是软件开发工具包,它是将一组功能相对完整的工具封装在一起的一个工具包。

所谓RPC本地调用:猜测你想表达的应该是进程间调用与进程内调用。进程内调用,因为进程内资源共享,即可以访问相同的内存地址,其实就是堆内存数据。

SDK则是为了方便适配某种特定语言,开发的工具包。


举例如开源软件MinIO
它提供基于HTTP API接口,兼容亚马逊S3协议。

如 获取Object接口
image.png

很多语言对这个HTTP协议做了封装,方便不同的语言进行使用。其实就是SDK

这些SDK的本质就是将函数调用转化为HTTP API的调用。

image.png

假设一个是php系统,一个java系统,他们是由两个团队维护,这时候如果使用RPC调用就不需要使用其他方案来引入依赖了

“但是我发现这些接口也可以以 sdk 的方式提供给其他服务调用” 这句话就证明了你的场景最佳做法是SDK提供,而不是API提供! 走TCP的socket三次握手,四次挥手,序列化,反序列化,网络传输这么绕一大圈,除非有特殊要求有这个必要,否则优先考虑SDK提供!

在微服务架构项目中选择使用 RPC 而非 SDK 方式提供相关能力,我认为最大的考虑是充分利用微服务架构的快速迭代优势,那么这个问题可以从微服务架构应用(和单体应用比较)和面向接口编程的优势两方面回答。
在说微服务架构应用优势之前,先说说单体应用的痛点。以Java单体应用为例,随着业务迭代发展,项目逐渐庞大,每一次上线后的白名单验证、回归测试一旦有问题就得回炉重造,可谓"牵一发而动全身",效率非常低下,无法达到快速迭代的目的。微服务框架将一个大型应用拆分成了更细粒度且边界清晰的服务模块,每个服务独立测试、部署,因此能够实现快速迭代、快速回滚。如果在迭代过程中出现线上 bug,也可以在最短时间内做线上回滚,并且不会影响到其他应用的正常发布。而在微服务架构使用 sdk 方式提供相关能力,相当于又回到了单体应用,并没有利用到微服务架构的快速迭代、回滚的优势。
其次是面向接口编程的优势,使用 RPC 时,一般的做法是先找服务提供方要接口,通过 Maven 导入依赖,在编写业务代码过程中,如果需要调用提供方的接口,只需通过依赖注入把接口注入到项目中,然后直接调用接口的方法即可。而使用 sdk 方式时,一般是直接调用具体实现类方法,这通常会导致代码高度耦合,缺乏灵活性和可扩展性,如修改实现时需要修改所有依赖代码、不能轻易替换不同的实现等。在微服务架构中,基于接口编程尤为重要,因为微服务强调服务之间的独立性和松耦合。通过使用接口定义,服务的实现可以灵活变动,而不影响其他服务。这种方式不仅提高了服务的可维护性,还增强了系统的扩展性和容错能力。
从上面两方面分析来看,在微服务架构中使用 sdk 方式提供相关能力在迭代速度、项目可扩展性灵活性以及性能方面不合理,也就会被 RPC 方式取代。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏