当前位置: 首页 > 科技观察

开发中的坑2:MQ也能做RPC调用吗?

时间:2023-03-23 01:48:14 科技观察

本文转载自微信公众号“HHFCodeRv”,作者haohongfan。转载本文请联系HHFCodeRv公众号。大家好,我叫郝红凡。最近在浏览帖子[1]时,看到一个有趣的抱怨。大概意思是架构师没有选择RPC框架来进行服务间调用,而是选择了使用MQ。是惊喜吗?当然,不出意外,评论区炸了!现在我问一些问题:架构师的做法对吗?MQ可以进行RPC调用吗?RPC框架的职责在回答上述问题之前,我们先了解一下RPC框架。目前市面上流行的RPC框架并不多。Java:SpringCloud、Dubbo等Go:Dubbogo、go-micro、rpcx、go-zero等其他:Thrift、gRPC等当然还有其他的框架,这里就不一一列举了。RPC虽然那么多,但是大家做的事情基本一样,都是服务间稳定、高效、准确的远程调用。说起RPC,大部分人都会下意识的想到gRPC。但是gRPC只是提供了服务间通信的能力,并不具备开源对应的管理服务的能力,需要二次开发。节俭也有同样的问题。下面以Dubbogo为例简单介绍一下Dubbogo实现的功能。Dubbo-go还具有以下特点:传输支持http2双向流模式rpc应用级服务发现与Dubbo(Java)版本对齐,可以相互稳定通信,也打通了与其他微服务框架的通信,例如:SpringCloud,综上所述,Dubbo-go为了保证数据的准确、高效、稳定传输做了各种架构设计。随着dubbo3.0的发布,在易用性、超大规模微服务实践、云原生基础设施适配等几大方向进行了全面升级。MQ而不是RPC?接下来,MQ是否可以替代RPC。来看看八卦随笔写的MQ的主要特点:服务间解耦最终一致的流量削峰异步消费MQ是微服务框架必不可少的组成部分,以上特点是我们日常开发中最常用的.这些特性确实可以增强系统的稳定性,同时也为系统的构建提供了更多的可能性。但是是否可以用MQ代替RPC来进行服务间的调用呢?在回答这个问题之前,我们先了解一下RPC是如何工作的。大致流程(数据摘自dubbogo网站[2])与本地调用类似,Client调用远程服务。客户端存根接收调用并序列化调用方法和参数。客户端通过套接字向服务器发送消息。Serverstub收到消息后,发送消息Object反序列化Serverstub根据解码结果调用本地服务,并将结果返回给ServerstubServerstub将返回结果序列化,通过sockets发送消息给客户端Clientstub接收结果消息并反序列化返回的消息客户端得到最终结果RPC调用简单概括就是Client通过TCP调用Server的一个函数得到返回结果。更简单一点,是不是可以把下面两个过程拆分开来:Client发起调用ServerServer返回一个结果给Client那么可以用MQ来模拟这个过程。当然,我并不是盲目的写这个过程。这是RabbitMQ的官方教程Remoteprocedurecall(RPC)[3]。有兴趣的可以看文末的参考链接。RabbitMQ教程一文基本上是对MQ替代RPC的理论支撑,所以文章开篇提到的Java架构师的解决方案并不是漫无目的,也不是错误的。MQ替代RPC的真实情况。正常情况有点大。互联网公司内部都会有一套RPC框架,或者基于开源版本二次开发,或者完全自研,用过或者维护过公司框架的都会被各个公司使用。问题被折磨死,比如:限流、熔断、重试、服务注册发现、网络问题、SDK升级等,如果可以用MQ代替RPC进行服务间调用,那么只需要维护一套MQ基础组件,既减少了人力配置,又总结了问题。理想是丰满的,但现实往往是残酷的。如果你下意识地搜索一下:使用MQ代替RPC进行服务间通信,你会发现网上只有几个demo,真正实践的并不多。实践不多不代表没有人真正在项目中战斗过,比如Java架构师。我曾经专门向朋友询问过这种设计。据说曾经有一个大厂在某个项目中实践了MQ而不是RPC,但是项目不到三个月就被干掉了。所以你看不出这个设计方案的缺点:因为很多人无法发布失败案例。简单说一下这个方案的缺点:一个TCP通信可以做的事情,使用MQ后会拆分成四个TCP,耗费大量时间。目前MQ的消费端大多是Pull模型,有一定的耗时成本。服务间调用完全依赖于MQ的稳定性。从目前使用MQ的经验来看,MQ稳定性的维护成本要比RPC复杂的多。如果做异步调用还能容忍错误和延迟,而做同步调用,这些都是不容忽视的问题。如果用MQ代替RPC,那些RPC框架的服务管理都需要实现MQ,工作量不大。减少。..现在说一下统一的结论:用MQ代替RPC只是一个理论,高可用是无法保证的,对于业务发展来说更是黑箱。万一有问题,就只能干瞪眼了。不推荐业务开发实践。