02.29 微服务调用为啥用RPC框架,http不更简单吗?

段勇宾


实际原因应该是比较简单的,阿里构建dubbo应该是为了将单一系统分拆程多个系统,为了最小化减少已有系统改造的工作量,所以出现了rpc,目前在金融行业定长报文,变长报文等都是很成熟的,还有spring cloud,如果是一开始就搭建框架,建议用springcloud这样的http协议,不建议用rpc这些框架,在跨语言调用的时候就会出现很大的问题


飘不远了


RPC:Remote Procedure Call,中文意思就是远程过程调用。

那么我们先看看题目中的问题,其实,这个问题本身就是有问题的!


01. 既然有 HTTP ,为什么还要用 RPC ?

HTTP 和 RPC 并不是两个并行的概念,虽然很多书或文章,都介绍 HTTP 和 RPC 是在“应用层”,但实际上可以把应用层细分成多层,RPC 的所处的位置是高于 HTTP 的;HTTP 是网络协议,而RPC 可以看做是一种编程模式或实现方案;

RPC 通常包含传输协议和序列化协议,单说传输协议,RPC 可以建立在 TCP 协议之上(比如 Dubbo),也可以建立在 HTTP 协议之上(比如 gRPC);如果是基于数据形式分类,RPC 又可以分成基于二进制、XML 和 JSON 三种;

而现在非常流行的开源 RPC 框架,比如上文中提到的Dubbo 和 gRPC 分别出身于阿里和谷歌,它们更多地是封装了服务注册发现、负载均衡、链路跟踪等功能,也可以这么理解,RPC 框架是对服务更高级的封装。


02. RPC VS Restful 风格的 API

如果非要比较的话,可以比较 RPC 和 Restful 风格的 API。

  • RPC:面向过程,也就是要做一件什么事情,只发送 GET 和 POST 请求;GET 用来查询信息,其他情况下一律用 POST;请求参数是动词。

  • RESTful:面向资源,这里的资源可以是一段文字、一个文件、一张图片,总之是一个具体的存在,可以使用 GET、POST、DELETE、PUT 请求,对应了增删查改的操作;请求参数是名词。

比如按照id 查找用户:

  • 如果是 RPC 风格的 url 应该是这样的:GET /queryUser?userid=xxx;

  • 而 RESTful 风格通常是这样的:GET /user/{userid}


03. 究竟选择哪一个?

RPC 特别适用于是分布式环境;它让客户端进行远程调用时,可以像调用本地方法一样方便;RPC 框架屏蔽了很多底层的细节,开发人员不需要关注这些细节,比如序列化和反序列化、网络传输协议;一些功能强大的 RPC 框架还提供了连接池管理、负载均衡、故障转移、超时管理、上下文管理器、异步回调、收发包队列、工作线程等功能。


RPC 和 Restful 风格的 API,如果非要争出来个第一第二,那么也要结合具体的使用场景,选择更适合的那个。

如果是偏向内部的 API,提供的 API 很难进行资源的抽象,没有规范的 API 的设计,性能要求更高,这些情况下更适合使用 RPC ;如果偏向外部 API,需要有更为规范的 API 设计,并且 API 天生是以资源为维度展开的,这时候可以选择 Restful 风格的 API。

我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。


会点代码的大叔


为什么服务之间调用,选择用RPC,http 不也能实现服务之间的通信吗?怎么不用呢?或者 RPC 比 http 好在哪里?

什么是RPC

提到RPC(Remote Procedure Call),就躲不开提到分布式,这个促使RPC诞生的领域。

假设你有一个Calculator,以及它的实现类CalculatorImpl,那么单体应用时,要调用Calculator的add方法来执行一个加运算,你可以方法中直接使用,因为在同一个地址空间,或者说在同一块内存,这个称为本地函数调用。

现在,将系统改造为分布式应用,接口调用和实现分别在两个子系统内,

服务A里头并没有CalculatorImpl这个类,那它要怎样调用服务B的CalculatorImpl的add方法呢?可以模仿B/S架构的调用方式,在B服务暴露一个Restful接口,然后A服务通过调用这个Restful接口来间接调用CalculatorImpl的add方法。

这样,已经很接近RPC了,不过,像这种每次调用时,是不是都需要写一串发起http请求的代码呢?比如httpClient.sendRequest...之类的,能不能简单一下,像本地方法调用一样,去发起远程调用,让使用者感知不到远程调用的过程。

屏蔽的工作,可以使用代理模式解决,生成一个代理对象,而这个代理对象的内部,就是通过httpClient来实现RPC远程过程调用的。

这就是很多RPC框架要解决的问题和解决的思路,比如阿里的Dubbo。

总结一下,RPC要解决的两个问题:

1. 解决分布式系统中,服务之间的调用问题。

2. 远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑。

RPC是一种技术的概念名词

RPC=Remote Produce Call 是一种技术的概念名词,HTTP是一种协议,RPC可以通过 HTTP 来实现,也可以通过Socket自己实现一套协议来实现.所以题目可以换一种理解,为何 RPC 还有除 HTTP 之外的实现法,有何必要,毕竟除了HTTP实现外,私有协议不具备通用性.

RPC框架好处

http接口是在接口不多、系统与系统交互较少的情况下,解决信息孤岛初期常使用的一种通信手段;

优点就是简单、直接、开发方便。

如果是一个大型的网站,内部子系统较多、接口非常多的情况下,RPC框架的好处就显示出来了:

首先就是长链接,不必每次通信都要像http一样去3次握手什么的,减少了网络开销;

其次就是RPC框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。

最后是安全性。

rpc是一种概念,http也是rpc实现的一种方式。

论复杂度,dubbo/hessian用起来是超级简单的。

至于为什么用dubbo/hessian,有几点:

一是调用简单,真正提供了类似于调用本地方法一样调用接口的功能 。

二是参数返回值简单明了 参数和返回值都是直接定义在jar包里的,不需要二次解析。

三是 轻量,没有多余的信息。

四是便于管理,基于dubbo的注册中心。

RPC能解耦服务

RPC:远程过程调用。RPC的核心并不在于使用什么协议。RPC的目的是让你在本地调用远程的方法,而对你来说这个调用是透明的,你并不知道这个调用的方法是部署哪里。

通过RPC能解耦服务,这才是使用RPC的真正目的。RPC的原理主要用到了动态代理模式,至于http协议,只是传输协议而已。简单的实现可以参考spring remoting,复杂的实现可以参考dubbo。

rpc=socket + 动态代理

服务器通讯原理就是一台socket服务器A,另一台socket客户端B,现在如果要通讯的话直接以流方式写入或读出。这样能实现通讯,但有个问题。如何知道更多信息?

比如需要发送流大小,编码,Ip等。这样就有了协议,协议就是规范,就是发送的流中携带了很多的内容。那回到刚刚的问题。发送的内容就是文本类型,客户端就得序列化,那么常用的就有json,xml之类,如果想把内容变得更小,那就有二进制了。把文本变成二进制传递。

说到 rpc 与http接口,不要太复杂了。rpc 协议更简单内容更小,那么来说效率是要高一点

rpc 是什么?就是socket 加动态代理。

总结

学技术应该是知其然知其所以然,我们得明白什么场景,或者什么业务需要它,它能解决其他技术不能解决或者不方便解决的问题。

RPC是一个软件结构概念,是构建分布式应用的理论基础。就好比为啥你家可以用到发电厂发出来的电?是因为电是可以传输的。至于用铜线还是用铁丝还是其他种类的导线,也就是用http还是用其他协议的问题了。这个要看什么场景,对性能要求怎么样。

在java中的最基本的就是RMI技术,它是java原生的应用层分布式技术。我们可以肯定的是在传输性能方面,RMI的性能是优于HTTP的。

那为啥很少用到这个技术?那是因为用这个有很多局限性,首先它要保证传输的两端都要要用java实现,且两边需要有相同的对象类型和代理接口,不需要容器,但是加大了编程的难度,在应用内部的各个子系统之间还是会看到他的身影,比如EJB就是基于rmi技术的。

这就与目前的bs架构的软件大相径庭。用http必须要服务端位于http容器里面,这样减少了网络传输方面的开发,只需要关注业务开发即可。所以在架构一个软件的时候,不能一定根据需求选定技术。


Java架构达人


微服务调用为啥用RPC框架,Http不更简单吗?

背景

在一次的面试交谈中,聊到业务实现的技术架构。不管系统大小,一般都是微服务的架构,所以就产生了一个问题,为什么服务之间调用,选择用RPC,http 不也能实现服务之间的通信吗?怎么不用呢?或者 RPC 比 http 好在哪里?

什么是RPC

提到RPC(Remote Procedure Call),就躲不开提到分布式,这个促使RPC诞生的领域。

假设你有一个Calculator,以及它的实现类CalculatorImpl,那么单体应用时,要调用Calculator的add方法来执行一个加运算,你可以方法中直接使用,因为在同一个地址空间,或者说在同一块内存,这个称为本地函数调用。

现在,将系统改造为分布式应用,接口调用和实现分别在两个子系统内,

服务A里头并没有CalculatorImpl这个类,那它要怎样调用服务B的CalculatorImpl的add方法呢?可以模仿B/S架构的调用方式,在B服务暴露一个Restful接口,然后A服务通过调用这个Restful接口来间接调用CalculatorImpl的add方法。

这样,已经很接近RPC了,不过,像这种每次调用时,是不是都需要写一串发起http请求的代码呢?比如httpClient.sendRequest...之类的,能不能简单一下,像本地方法调用一样,去发起远程调用,让使用者感知不到远程调用的过程。

屏蔽的工作,可以使用代理模式解决,生成一个代理对象,而这个代理对象的内部,就是通过httpClient来实现RPC远程过程调用的。

这就是很多RPC框架要解决的问题和解决的思路,比如阿里的Dubbo。

总结一下,RPC要解决的两个问题:

1. 解决分布式系统中,服务之间的调用问题。

2. 远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑。

RPC是一种技术的概念名词

RPC=Remote Produce Call 是一种技术的概念名词,HTTP是一种协议,RPC可以通过 HTTP 来实现,也可以通过Socket自己实现一套协议来实现.所以题目可以换一种理解,为何 RPC 还有除 HTTP 之外的实现法,有何必要,毕竟除了HTTP实现外,私有协议不具备通用性.

RPC框架好处

http接口是在接口不多、系统与系统交互较少的情况下,解决信息孤岛初期常使用的一种通信手段;

优点就是简单、直接、开发方便。

如果是一个大型的网站,内部子系统较多、接口非常多的情况下,RPC框架的好处就显示出来了:

首先就是长链接,不必每次通信都要像http一样去3次握手什么的,减少了网络开销;

其次就是RPC框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。

最后是安全性。

rpc是一种概念,http也是rpc实现的一种方式。

论复杂度,dubbo/hessian用起来是超级简单的。

至于为什么用dubbo/hessian,有几点:

一是调用简单,真正提供了类似于调用本地方法一样调用接口的功能 。

二是参数返回值简单明了 参数和返回值都是直接定义在jar包里的,不需要二次解析。

三是 轻量,没有多余的信息。

四是便于管理,基于dubbo的注册中心。

RPC能解耦服务

RPC:远程过程调用。RPC的核心并不在于使用什么协议。RPC的目的是让你在本地调用远程的方法,而对你来说这个调用是透明的,你并不知道这个调用的方法是部署哪里。

通过RPC能解耦服务,这才是使用RPC的真正目的。RPC的原理主要用到了动态代理模式,至于http协议,只是传输协议而已。简单的实现可以参考spring remoting,复杂的实现可以参考dubbo。

rpc=socket + 动态代理

服务器通讯原理就是一台socket服务器A,另一台socket客户端B,现在如果要通讯的话直接以流方式写入或读出。这样能实现通讯,但有个问题。如何知道更多信息?

比如需要发送流大小,编码,Ip等。这样就有了协议,协议就是规范,就是发送的流中携带了很多的内容。那回到刚刚的问题。发送的内容就是文本类型,客户端就得序列化,那么常用的就有json,xml之类,如果想把内容变得更小,那就有二进制了。把文本变成二进制传递。

说到 rpc 与http接口,不要太复杂了。rpc 协议更简单内容更小,那么来说效率是要高一点

rpc 是什么?就是socket 加动态代理。

总结

学技术应该是知其然知其所以然,我们得明白什么场景,或者什么业务需要它,它能解决其他技术不能解决或者不方便解决的问题。

RPC是一个软件结构概念,是构建分布式应用的理论基础。就好比为啥你家可以用到发电厂发出来的电?是因为电是可以传输的。至于用铜线还是用铁丝还是其他种类的导线,也就是用http还是用其他协议的问题了。这个要看什么场景,对性能要求怎么样。

在java中的最基本的就是RMI技术,它是java原生的应用层分布式技术。我们可以肯定的是在传输性能方面,RMI的性能是优于HTTP的。

那为啥很少用到这个技术?那是因为用这个有很多局限性,首先它要保证传输的两端都要要用java实现,且两边需要有相同的对象类型和代理接口,不需要容器,但是加大了编程的难度,在应用内部的各个子系统之间还是会看到他的身影,比如EJB就是基于rmi技术的。

这就与目前的bs架构的软件大相径庭。用http必须要服务端位于http容器里面,这样减少了网络传输方面的开发,只需要关注业务开发即可。所以在架构一个软件的时候,不能一定根据需求选定技术。


三年起步


RPC名称是远程服务调用。这里面实际是没有限制一定会是tcp,也可以是http或者其他基于tcp协议的服务。

远程服务调用,有多种 ,http的接口调用,基于http的webservice,java中的rmi 实际都算是rpc。为什么都向长连接改动。是因为技术性能的要求越来越高,必然带来这样的发展趋势。

http接口,简单通用,但是调用放需要编写大量的代码去解析返回结果,并且http性能并不高效,除了header的问题之外,早期的http还不能多路复用。

webservice实际上是http协议之上的封装,它更多是为了解决http接口调用需要编写大量客户端解析参数代码产生的,它能帮助少写代码,但无法改善http的性能。

java的rmi 典型的就是ejb 现在新的java程序员可能都没听过这玩意,这也是基于长连接实现,基于java的序列化。它能够解决客户端参数解析的问题,也能多路复用socket 但是ejb本身的复杂性以及java序列化低效的问题导致它也是被放弃,并且它是不能跨语言的。

现在的rpc框架大多都是基于socket长连接,自定义协议实现。采用的序列化方式也会比较高效和跨语言。比如grpc 采用protobuf做序列化,采用http2做传输协议。

从某种意义上来讲,http接口也能算是rpc调用,只是需要更具开发工作量以及性能指标做技术抉择。


LKC444


都没说到点子上。微服务使用的RPC是基于HTTP2的gRPC,传输格式使用binary的protobuf,比json更快,HTTP2支持multiplexing, concurrency, streaming。


Yan142040965


首先微服务也有用http的,现在流行的feign,底层就是http,也是我们经常提到的restful编程方式。

Rpc在国内最具有代表的是dubbo,底层可以选择netty进行通讯,速度肯定是比http快的。

但是微服务不是一个简单的调用,涉及到很多方面,比如容错,高并发,熔断,事务等等。普通的http代码是无法解决这些问题的。一般需要很多组件来配合,比如feign就要配合robbin,hystrix等来配合,dubbo也需要zookeeper来配合。

所以这两者在我们的开发中,都很常见。


老牛视频剪辑


RPC只是微服务使用的一种协议,微服务也支持HTTP。

RPC都提出了超过20年了,微服务提出才不到10年。

微服务是SOA基础上进化而来的,解决的是传统继承方案的中心化部署(从而导致不宜扩展)、臃肿(服务太大粒度不够小)等问题。


子非鱼137819


微服务强调的是传输效率,http传输效率过低,携带头部信息影响传输更多的信息,而rpc是一种专门设计用来进行远程调用的消息传输机制,传输效率高,微服务非常强调时延性,而rpc解决了这个问题,所以大家更喜欢使用它。

但是没有任何事情是绝对的,毕竟http相比较而言,更加方便,有时候也会使用它。


梦回故里归来


rpc异步非阻塞多线程,http同步阻塞单线程服务足够微,效率也不比rpc差,服务太小太多小项目成本也很高。所以看情况用。http也可以用mq做异步非阻塞提高效率,成本也很高。


分享到:


相關文章: