在微服务中是用队列好还是 RPC 好

2019-07-04 18:11:01 +08:00
 springmarker

个人浅薄的认识,在大多数场景下可以用队列替换 RPC(指代通常的 RPC,不是由队列实现的 RPC)。
队列的优点:
1.消息可以堆积,只要队列稳定,消息丢失的概率就比直接 RPC 低。
2.由接收端主动获取消息的话,负载就由接收端控制了,不会像 RPC 一样无法均衡的负载。
3.没有类似 Zookeeper 的注册中心,发送端和接收端只要面对队列就可以,发送端不用同时面对注册中心和多个接收端。

缺点的话就是性能不如直接 RPC、需要手动写异步转同步。

我看很多微服务都用的是 GRPC 和 Dubbo 之类的 RPC,甚至 Spring Cloud 的 RPC,如果替换成队列会有什么影响吗?不需要高性能的场景下可以互相替换吗?

本人了解甚少,上面都是班门弄斧的瞎说,如有不对,希望大神能指教一二。

16823 次点击
所在节点    程序员
129 条回复
l8g
2019-07-04 20:49:59 +08:00
@springmarker RPC 当然也要来回发送 但 RPC 本身就不是为了解耦
springmarker
2019-07-04 21:00:45 +08:00
@NewDraw #40 我觉得有“微服务”,“ RPC ”,“队列”这三个关键词,不是很容易想到消息队列吗?
最坏的情况是请求带标志头,让服务端判断放在哪个队队列,最坏的情况队列 数量 =( Client+1 ),如果有类似 ActiveMQ 的消息过滤器的功能,队列数量就可以缩减到两个。
springmarker
2019-07-04 21:05:32 +08:00
@petelin #38 传统 RPC 没有消息冗余、解耦等队列的特性
ntop
2019-07-04 21:12:44 +08:00
当然是可以的,我司现在就是在 80% 的场景上使用消息队列取代 RPC,从本质上看消息队列和 RPC 都是一个消息管道,如果消息采用对方确认返回的模式那么和 RPC 在行为上就一致了。消息在性能上可能不如 RPC,我司现在用的是 NATs 一个 go 写的超高性能的消息系统,只有极个别对性能要求甚高的系统采用 RPC 直连。我司主要做社区 /论坛系统的,目前还没有遇到啥问题。
NewDraw
2019-07-04 21:17:33 +08:00
@springmarker

探讨问题应该把题目说清楚,而不是让别人去猜,总之很别扭。
如果完全不考虑性能因素,只关注实现功能,那么消息队列确实能实现 rpc 的所有功能,无论异步还是同步。
但是本质上来说消息队列和 rpc 都是基于 tcp 链接,所以似乎没有什么突破。
springmarker
2019-07-04 21:26:44 +08:00
@NewDraw #45 大家都认为传统 RPC 的主要功能就是同步调用,但是使用同步 RPC 调用本身就是高性能编程的大忌(指无协程的语言),我想用队列实现类似 RPC 的功能 其实更想要的是队列的特性所带来的好处。
gz911122
2019-07-04 21:42:42 +08:00
@zhangtao rest 怎么就同步了呢?rpc 怎么就同步了呢?
异步 rest 不比同步的多多了?
gz911122
2019-07-04 21:43:36 +08:00
@zhangtao 你的理解严重有问题
billlee
2019-07-04 21:48:58 +08:00
akka 了解一下
springmarker
2019-07-04 22:24:05 +08:00
@l8g #41 我没说 RPC 是用来解耦的,难道拥有解耦的特性不好吗
ccpp132
2019-07-04 22:25:38 +08:00
用队列实现 rpc 就是 rpc,和其他的 rpc 比没更多好处。
另外这是一个不同层面的东西,你实现一个消息队列服务也要通过 rpc 把新的请求放入队列中,所以不可能脱离 rpc
windfarer
2019-07-04 22:25:44 +08:00
zeromq 了解一下
springmarker
2019-07-04 22:31:32 +08:00
@ccpp132 #51 1.一开始括号里我也说了,指的是以传统 RPC 来比较。2.为什么要通过 RPC 把消息放入队列,直接用消息队列的驱动放进去不好吗?
ccpp132
2019-07-04 22:36:38 +08:00
@springmarker 你想想,消息队列的驱动怎么做,是不是要发消息给消息队列的服务器,是不是要收响应看是否成功,是不是要处理失败重试负载均衡等问题,这不就是一个 rpc
springmarker
2019-07-04 22:44:12 +08:00
@ccpp132 #54 额,这样理解的话,连接数据库也属于一个 RPC 了。
关于检查成功、重试等问题,也是事先想到了,因此性能肯定不如直接传统 RPC 调用,一开头我也说了。
也正因是如此复杂,所以带来了队列的一些特性,开头我也说了。
ccpp132
2019-07-04 23:00:21 +08:00
@springmarker 你先想明白一点,rpc 就是这么个概念,同步请求得到结果。和底下的实现关系不大。现在的优缺点放你用 mq 实现也还是一样,不会变的,要不然人家 grpc 底层就改掉就完了。
springmarker
2019-07-04 23:11:03 +08:00
@ccpp132 #56 你是用传统 RPC 和由 MQ 实现的“ RPC ”直接进行比较,我想的是在微服务中他俩效果有什么差距,我并不希望由 MQ 实现的“ RPC ”是同步调用,本来就不符合队列的特性,只是利用它来传输信息并异步返回数值,同时拥有 MQ 的特性。
springmarker
2019-07-04 23:17:08 +08:00
@ccpp132 #56 我一开始想问的就是在最大利用 MQ 特性实现异步“ RPC ”的特性的同时,他俩效果有什么差距,我也并不想鼓吹队列多么多么好,只是上面很多人回答的不到点上。
chinvo
2019-07-04 23:22:00 +08:00
#迷惑行为大赏
ccpp132
2019-07-04 23:35:42 +08:00
rpc 和 mq 这两个东西的层次有一些不同,直接放一起比是容易跑偏,主要是两者也不是可以完全互相替代的。你应该也明白如果就是需要一个同步操作的时候,用队列实现 rpc 不会有太多的优点。除非是处理时间非常长的任务,你不能接受网络连接断开进行重试。因为异步的模型就是比同步的更难理解和维护,所以大家都愿意用 rpc

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/580080

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX