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

开发 项目管理
用 MQ 代替 RPC 只是一种理论,但是高可用无法保障,而且对业务开发来说就更加黑盒了,出现问题就只能干瞪眼了,不建议业务开发实践。

[[409473]]

本文转载自微信公众号「HHFCodeRv」,作者haohongfan。转载本文请联系HHFCodeRv公众号。

hi, 大家好,我是 haohongfan。

最近浏览 帖子[1] 的时候看到一个有意思的吐槽。

大概意思是架构师没有选用 RPC 框架来做服务间调用,而选择用 MQ 来代替。是不是很意外?

当然不出意外的,评论区炸了!

 

现在提出一些疑问:

  • 这个架构师的做法对吗 ?
  • MQ 是否能做 RPC 调用 ?

RPC 框架的职责

回答上面问题之前,稍微捋一下 RPC 框架。目前市面上比较流行的 RPC 框架其实并不多。

  • Java: SpringCloud,Dubbo 等
  • Go: Dubbogo,go-micro,rpcx,go-zero 等
  • 其他:Thrift,gRPC 等

当然还有其他的一些框架,这里就不再罗列。虽说 RPC 多如牛毛,但是大家干的事情基本都差不多,都是稳定,高效、准确的进行服务间远程调用。

说起 RPC 应该大部分人下意识会联想到 gRPC,不过 gRPC 只提供的了服务间通信的能力,但却没有开源对应的服务治理的能力,需要进行二次开发。Thrift 也是同样的问题。

下面以 Dubbogo 为例,大概介绍下 Dubbogo 实现的功能。

Dubbo-go 还有下面这些特点:

  • 传输支持 http2
  • 双向流模式 rpc
  • 应用级服务发现

跟 Dubbo(Java) 版本对齐,互相之间能稳定通信,同时也打通与其他微服务框架的通信,如:SpringCloud、gRPC

综上,Dubbo-go 为了保证数据准确、高效、稳定传输,做了各种各样的架构设计。随着 dubbo 3.0 的发布,在易用性、超大规模微服务实践、云原生基础设施适配等几大方向上进行了全面升级。

MQ 代替 RPC ?

接着说 MQ 是否能替代 RPC。先看看 MQ 被写进八股文里面的几大特性:

  • 服务间解耦
  • 最终一致性
  • 流量削峰
  • 异步消费

MQ 是微服务框架中必不可少的一环,上面的特性是我们日常开发中最常用的。这些特性确实能让系统的稳定性得到增强,同时也让系统的构建出现更多的可能性。

但是是否能让 MQ 来代替 RPC,做服务间的调用?回答这个问题之前,我们再来看看 RPC 是如何工作的。

大概流程(资料节选 dubbogo website[2])

  • 类似本地调用,Client 调用远程服务
  • Client stub 收到调用,把调用方法、参数序列化
  • Client 通过 socket 把消息发送到服务端
  • Server stub 收到消息后,将消息对象反序列化
  • Server stub 根据解码结果调用本地的服务,并将结果返回给 Server stub
  • Server stub 将返回结果序列化,通过 sockets 将消息发送到客户端
  • Client stub 接收到结果消息,对返回消息反序列化
  • 客户端得到最终结果

简单概括下 RPC 调用就是 Client 通过 TCP 调用 Server 的一个函数,得到一个返回结果。

再简单点,是不是可以拆分下面两个过程:

  1. Client 发起一个调用到 Server
  2. Server 返回一个结果到 Client

那么是不是可以用 MQ 模拟这个过程。

当然这个流程并不是我瞎写的,这是 RabbitMQ 的官方教程 Remote procedure call (RPC)[3],有兴趣的可以看文末的参考链接。

RabbitMQ tutorial 这篇文章基本就是 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 只是一种理论,但是高可用无法保障,而且对业务开发来说就更加黑盒了,出现问题就只能干瞪眼了,不建议业务开发实践。

 

责任编辑:武晓燕 来源: HHFCodeRv
相关推荐

2021-07-15 11:31:22

递归匹配参数

2021-12-28 08:17:41

循环 forgo

2015-04-13 17:39:11

移动IM开发

2020-12-11 07:39:37

RPC MQ架构

2012-03-16 17:19:28

2021-11-15 14:02:27

RPCSpringBootRabbitMQ

2021-06-30 07:19:35

微服务业务MySQL

2011-02-28 10:01:00

芯片有机塑料

2017-03-02 13:32:36

Android开发开发者

2017-09-28 15:07:37

全局字体反射

2014-09-02 10:43:45

RedisRPC

2024-05-31 08:45:24

2021-04-22 07:47:47

JavaJDKMYSQL

2022-04-02 07:52:47

DubboRPC调用动态代理

2023-01-18 08:32:13

2011-07-14 11:28:16

360安全浏览器

2022-06-30 08:58:09

时钟轮RPC框架

2017-08-08 11:15:29

笔记本Titan XpQuadro

2021-03-31 11:53:30

人工智能整形美容

2020-03-30 09:22:36

C语言结构体
点赞
收藏

51CTO技术栈公众号