远程调用服务(RPC)和消息(Message Queue)对比及其适用/不适用场合

本文转载,因网上版本几乎都是转载,故不知道哪个才是原版。
重点是共享知识!

在阿里的平台技术部参与开发了Dubbo(远程调用服务)和Napoli(消息解决方案),又给网站应用支持这2个产品2年,了解了这2个产品的实现及应用对这两个产品的用法。

大部分情况下,“给定场景下应该使用这两个产品中哪个”这个问题,大家都会容易决定,而且不需要多少讨论。

我为什么要拿出来讨论一下:

一些场景会比较模糊,觉得都可以使用。这时需要知道产品缺点,而不是看到优势。
一些新人会觉得产品功能是可以替换的,要给说明一下。
这里简单说一下两者的区别。

系统结构

RPC系统结构:

+———————————–+
| Consumer | <=> | Provider |
+———————————–+
Consumer调用的Provider提供的服务。

Message Queue系统结构:

+—————————————————+
| Sender | <=> | Queue | <=> | Receiver |
+—————————————————+
Sender发送消息给Queue;Receiver从Queue拿到消息来处理。
RPC系统结构:

+———————————–+
| Consumer | <=> | Provider |
+———————————–+
Consumer调用的Provider提供的服务。

Message Queue系统结构:

+—————————————————+
| Sender | <=> | Queue | <=> | Receiver |
+—————————————————+
Sender发送消息给Queue;Receiver从Queue拿到消息来处理。

功能特点

在架构上,RPC和Message的差异点是,Message有一个中间结点Message Queue,可以把消息存储。

消息的特点

Message Queue把请求的压力保存一下,逐渐释放出来,让处理者按照自己的节奏来处理。
Message Queue引入一下新的结点,让系统的可靠性会受Message Queue结点的影响。
Message Queue是异步单向的消息。发送消息设计成是不需要等待消息处理的完成。
所以对于有同步返回需求,用Message Queue则变得麻烦了。

RPC的特点

同步调用,对于要等待返回结果/处理结果的场景,RPC是可以非常自然直觉的使用方式。
RPC也可以是异步调用。
由于等待结果,Consumer(Client)会有线程消耗。
如果以异步RPC的方式使用,Consumer(Client)线程消耗可以去掉。但不能做到像消息一样暂存消息/请求,压力会直接传导到服务Provider。

适用场合说明

希望同步得到结果的场合,RPC合适。
希望使用简单,则RPC;RPC操作基于接口,使用简单,使用方式模拟本地调用。异步的方式编程比较复杂。
不希望发送端(RPC Consumer、Message Sender)受限于处理端(RPC Provider、Message Receiver)的速度时,使用Message Queue。
随着业务增长,有的处理端处理量会成为瓶颈,会进行同步调用到异步消息的改造。

这样的改造实际上有调整业务的使用方式。

比如原来一个操作页面提交后就下一个页面会看到处理结果;改造后异步消息后,下一个页面就会变成“操作已提交,完成后会得到通知”。

不适用场合说明

RPC同步调用使用Message Queue来传输调用信息。 上面分析可以知道,这样的做法,发送端是在等待,同时占用一个中间点的资源。变得复杂了,但没有对等的收益。

对于返回值是void的调用,可以这样做,因为实际上这个调用业务上往往不需要同步得到处理结果的,只要保证会处理即可。(RPC的方式可以保证调用返回即处理完成,使用消息方式后这一点不能保证了。)

返回值是void的调用,使用消息,效果上是把消息的使用方式Wrap成了服务调用(服务调用使用方式成简单,基于业务接口)。

补记,关于解耦讨论

微博上 inter12 的一些讨论,觉得很有意义补记下来。

inter12:这两者可以拿来比较,但是个人感觉并不是同一个层面的问题。RPC是分布式服务之间调用的一种解决方案,是我们在做架构设计决策时同分布式对象,REST等层面的东西比较,决策的一个方案! 消息系统更多是我们为了解决系统之间的解耦,以及性能问题等方面所考虑的方案! 说的有些乱,望鼎哥指点下。

oldratlee:回复@inter12:你说到很多关键点了,“分布式对象”“解耦”“性能”,这些都可以用来看两者的差异。 如果从两个机器间数据的传递(调用、消息都是数据)角度看,两者效果相同,区别只是使用方式、技术指标:同步异步(比如 是否等反馈 )、数据是否暂存、强弱类型(比如 有独立的业务方法,数据类型)等等

inter12 提到了“解耦”,“解决系统之间的解耦”使用消息时大家常常说到的一点,一个重要权衡方面!

个人觉得,“解耦”不如“暂存”,是消息相对RPC的关键区别,原因说明如下:

消息的解耦特征,主要体现在:

消息的发送者,不需要关心接收者的信息。 服务通过注册中心也可以做到,即服务调用者到注册中心查询服务提供者信息,调用者不需知道。
消息的发送者,不用关心可以发个几个关心的消息组件。
这一点RPC可以通过服务编排做到。

时间: 2024-10-21 22:32:45

远程调用服务(RPC)和消息(Message Queue)对比及其适用/不适用场合的相关文章

架构设计:一种远程调用服务的设计构思(zookeeper的一种应用实践)

在深入学习zookeeper我想先给大家介绍一个和zookeeper相关的应用实例,我把这个实例命名为远程调用服务.通过对这种应用实例的描述,我们会对zookeeper应用场景会有深入的了解. 远程调用是系统与系统之间的通信机制,它的另一种理解就是进程间的通信.做分布式系统的开发,远程调用技术是其核心技术.远程调用技术可以将一组计算机系统形成一个网络系统,对外提供整体服务,那么这一群的计算机系统就构成了一个更大型,性能更高的计算机系统. 我在前面的博客里介绍了一种分布式网站的架构设计,其中就有一

【PHP】远程调用以及RPC框架

前言 一个项目,从开始到版本更新,一直到最后的版本维护.功能在不断增多,对应的代码量也在不断增加,也就意味着项目变得更不可维护,这时候,我们需要用拆分的方式将一个项目打散,以便开发团队更好的对项目进行维护. 分模块 这个阶段,一般也是项目的初级阶段,由于人手不够,一个服务端的接口项目只有一个开发进行维护,根据开发的习惯,会把项目分成若干个模块进行开发,在一个项目下进行部署. 这样做的缺点在于项目会随着版本更新而变得不可维护. 分项目 随着每个模块功能的不断完善,代码变得更加臃肿.这时候需要对项目

Python中实现远程调用(RPC、RMI)简单例子_python

远程调用使得调用远程服务器的对象.方法的方式就和调用本地对象.方法的方式差不多,因为我们通过网络编程把这些都隐藏起来了.远程调用是分布式系统的基础. 远程调用一般分为两种,远程过程调用(RPC)和远程方法调用(RMI). RPC RPC属于函数级别的远程调用,其多是通过HTTP传输数据,数据形式有XML.JSON.序列化数据等.在此,用python做一个xml-rpc的示例. 先给服务器端server.py: 复制代码 代码如下: from SimpleXMLRPCServer import S

基于Dubbo的Hessian协议实现远程调用

Dubbo基于Hessian实现了自己Hessian协议,可以直接通过配置的Dubbo内置的其他协议,在服务消费方进行远程调用,也就是说,服务调用方需要使用Java语言来基于Dubbo调用提供方服务,限制了服务调用方.同时,使用Dubbo的Hessian协议实现提供方服务,而调用方可以使用标准的Hessian接口来调用,原生的Hessian协议已经支持多语言客户端调用,支持语言如下所示: Java:http://hessian.caucho.com/#Java Flash/Flex:http:/

Android--绑定服务调用服务的方法

Service按照其启动的方式,可分为两种:1.StartedStarted的Service,通过在Application里用startService(Intent intent)方法来启动.这种类型的Service一经启动,会在后面无休止地运行,即使启动它的Activity被Destroy掉.要停止此类型的Service,可在Service中调用stopSelf()或在Application中调用stopService(Intent intent),要不然就只能等Android系统在系统资源紧

【spring源码学习】spring的远程调用实现源码分析

[一]spring的远程调用提供的基础类 (1)org.springframework.remoting.support.RemotingSupport ===>spring提供实现的远程调用客户端实现的基础类 ===>例子:org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean org.springframework.remoting.caucho.HessianProxyFactoryBean (2)org.

从远程调用框架认识Zookeeper

远程调用是系统或进程间的通信机制,是分布式系统开发的核心技术.远程调用技术可以将一组计算机系统形成一个网络系统,对外提供整体服务,那么这一群的计算机系统就构成了一个更大型.性能更高的计算机系统. 远程调用服务的架构设计总述 首先我们要深入理解以下几个问题:为什么应用软件服务里需要一个远程调用服务?远程调用服务解决了软件设计中的什么问题? 笔者曾写过一篇关于分布式网站架构设计的文章, 在文章开头就把这个新的网站架构方案和传统的企业软件的B/S架构作了对比,笔者将一个网站里提供业务服务的组件抽象为独

RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC)

        在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇文章中,我们将会通过其它节点求来斐波纳契完成示例. 1. 客户端接口 Client interface         为了展示一个RPC服务是如何使用的,我们将创建一段很简单的客户端class. 它将会向外提供名字为call的函数,这个call会发送RPC请求并且阻塞知道收到RPC运算的结果.代码

Openstack Nova 源码分析 — RPC 远程调用过程

目录 目录 Nova Project Services Project 的程序入口 setuppy Nova中RPC远程过程调用 nova-compute RPC API的实现 novacomputemanager 模块 最后 Nova Project Services nova-api:捕获novaclient发送过来的HTTP请求,并且将它转换为AMQP消息,通过Queue来与别的services通信. nova-conductor:为数据库访问提供了一层安全保障. NOTE:除了nova-