古老又有生命力的RPC
RPC (远程过程调用)是建立在套接字上的多进程通信机制。 与复杂的套接字通信方式不同,RPC的初衷是设计远程通信的通用框架。 该框架能够自动处理通信协议、对象序列化、网络传输等复杂细节。 另外,开发人员在使用该框架后,希望调用远程机器上的接口的代码和本地方法调用的代码“看起来没有太大变化”,从而大幅降低分布式系统的开发难度,使分布式系统的开发变得容易
为了便于理解socket通信和RPC通信在编程上的不同,我举个简单的例子进行说明。现在,假设B机有一个可以轻松实现四则运算的过程。 例如,如果输入1进行计算并返回计算结果,则在套接字上开发时,客户端的伪代码大致为:
客户端=新套接字(b;
client.write (加勒斯(1,1 ) );
result=客户端.读取(;
客户端(; 服务器端的伪代码大致为:
套接字服务器=新服务器套接字(;
server.listen (;
是wile (真)
{
cmd -服务器读(;
if (cmd .开始为(‘ plus ) ) )
{
你好吗
客户端.写入(结果;
}
{1}上述代码是简化后的大量伪代码,为了满足生产质量的要求,还需要考虑以下复杂问题。
如果在调用过程中发生网络异常,网络异常问题:将无法调用。 客户端必须明确知道发生了异常,并根据目的采取应对措施。 在复杂的数据传输中的编码和解码问题:输入参数或输出参数复杂的情况下,参数编码和解码中的复杂性往往会让思维不充分的程序员的头脑“短路”。 的连接复用问题在每次调用时建立TCP连接,在使用完毕并关闭后,调用性会降低。 由于建立TCP连接花费了大量的时间,客户端需要维护和复用连接的机制,还存在与服务器端和客户端的连接心跳检测和超时机制等相关的复杂问题。 为了提高性能,服务器端需要多线程机制来满足客户端的并发请求。 所以,即使有套接字,有优秀的NIO框架,也很少有人能开发出基于套接字的高质量远程通信模块,可见自由的分布式系统有很多远程通信的功能点。 这样,开发分布式系统仍然是一个难题。
于是,分布式系统中最重要的开发框架诞生了。 这就是有名的RPC。 RPC最初由Sun公司Sun RPC提出,后来成为IETF国际标准。 目前,重要的NFS协议仍然是第一个基于RPC的重要情况。
为了将传统程序改写为RPC程序,将另一个代码(称为Stub )添加到程序中。 想象一下以往的程序。 进程传输到远程机器,客户端和服务端各有一个Stub模块实现远程过程调用所需的通信功能,如参数和调用结果的串行化功能,通过网络完成远程传输。 因为Stub使用与原始服务器端相同的接口,所以添加这些Stub代码不需要更改原始客户端的调用逻辑
整个RPC的调用流程如下:
(1)服务消费端)客户端)通过本地呼叫调用服务。
(2) Client Stub在接收到调用后,有责任将方法、参数等组装成可以进行网络传输的报文主体。 )3) Client Stub找到服务器地址,向服务器端发送消息。
4 ) Server Stub在接收到消息后进行解码。
(5) Server Stub基于解码结果调用本地服务。 (6)本地服务被执行,结果被返回到Server Stub。
7 ) Server Stub将回复结果打包成消息发送给消费者。 8 ) Client Stub接收并解码消息。
)9)服务消费方将得到最终结果。
实现完整的RPC体系结构需要独特的技术,包括:
高性能网络编程技术。 对象(复杂的数据结构)序列化和反序列化技术。 自动代码生成或动态代理编程技术。 例如,Java经典的RPC实现方案RMI被用于Java的缺省序列化机制和动态代理编程技术。 但是,Java的RMI和其他语言的特定RPC架构经常有明显的缺点,即只有本语言的客户端调用,无法用其他语言进行调用。 开发需要支持多种语言的RPC体系结构变得至少困难了一位数。
人类历史上,支持多语言通信的第一次伟大尝试成功地产生了成功的CORBA技术。 1991年CORBA 1.1诞生,到1994年底完成了CORBA2.0标准。 该标准原本想解决不同制造商基于COBRA标准开发的产品“互联”的重大问题,但很遗憾失败了。 关于COBRA失败的原因,是COBRA技术的寒冷指甲油,COBRA技术的推动者,也就是后来加入的
“反COBRA阵营”的Michi Henning,在他的The rise and fall of CORBA书里做了如下深刻的总结。
规范巨大而复杂:许多特性都未曾实现,甚至概念性的证明都没有做过;有些技术特性根本不可能实现,即使实现,也无法提供可移植性。CORBA很难学习:平台的学习曲线陡峭,技术复杂,不容易正确使用,这些因素导致开发周期长、易出错。早期的实现常常充满 Bug 并且缺乏有质量的文档,有经验的CORBA程序员稀缺。编程开发过于复杂:有经验的CORBA开发者发现编写实用的CORBA应用程序相当困难。许多API 都很复杂、不一致,甚至让人感觉神秘,使得开发者必须关注许多细节问题。相比之下,组件模型的简单性,例如同时代的EJB,使得编程简单很多。贤惠的导师:在使用商用CORBA 产品时,开发者一般都需要花费几千美元购买开发者License,此外,部署CORBA产品与部署Oracle数据库一样,还需要客户支付企业License费用,而且这个费用很可能与部署在CORBA平台上的应用数量挂钩,因此对很多潜在的客户来说,CORBA这样的平台太昂贵了。Sun 与Java成为COBRA最大的竞争对手:商业公司转向了Sun的Java与新兴的Web,并且开始构建基于Web浏览器、Java和EJB的电子商务基础设施。XML技术的兴起加速了COBRA 的没落:20世纪90年代后期,XML成为计算机工业新的银弹,几乎被定义为XML的事物都是好的。在放弃了DCOM 之后,微软并没有把电子商务市场留给竞争对手,没有再参与一场不可能打赢的战争,而是使用XML开辟了新的战场。1999年年底,工业界看到了SOAP的发布。SOAP由微软和DevelopMentor 发布,随后提交给W3C作为标准。SOAP使用XML作为RPC新的对象序列化机制,IBM则又继续发扬光大这条路线,推出Web Service等整套方案。
SOAP在严格意义上是属于XML-RPC (XML Remote Procedure Call)技术的一个变种,一个XML-RPC请求消息就是一个HTTP-POST 请求消息,其请求消息主体基于XML格式。客户端发送XML-RPC 请求消息到服务端,调用服务端的远程方法并在服务端运行远程方法。远程方法在执行完毕后返回响应消息给客户端,其响应消息主体同样基于XML格式。远程方法的参数支持数字、字符串、日期等,也支持列表数组和其他复杂结构类型。SOAP也是第一次真正成功地解决了多语言多平台支持的开放性RPC标准。
一个SOAP请求报文实例(查询股票价格)如下:
<?xml version=”1.0″?><soap :Envelope
xmlns:soap=”http://www.w3.org/2001/12/soap-envelope”
soap:encodingStyle=”http://www .w3.org/2001/12/soap-encoding”><soap:Body xmlns:m=”http://www.example.org/stock”>
<m:GetStockPrice>
<m: StockName>IBM</m:StockName></m:GetStockPrice>
</soap:Body>
</soap :Envelope>
对应的应答报文实例如下:
<?xml version=”l.0″2><soap:Envelope
xmlns:soap=”http://www.w3.org/2001/12/soap-envelope”
soap:encodingstyle=”http:/ /www .w3.org/2001/12/soap-encoding”><soap:Body xmlns:m=”http://www.example.org/stock”>
<m :GetStockPriceResponse>
<m: Price>34.5</m:Price></m: GetStockPriceResponse></soap:Body>
</soap:Envelope>
我们看到,SOAP 的报文很复杂而且编码臃肿,由于它是面向机器识别的表达格式,所以程序员很难直接理解它的报文,该缺陷最终导致了SOAP的末路与HTTP REST的通信方式的兴起。HTTP REST采用了让人容易理解的JSON格式来传递请求与应答参数,因而开发更为方便,但HTTP REST已经脱离了RPC的范畴,最明显的几个特征:它无须客户端Stub代码与服务端Stub 代码,调用也不再类似于本地方法调用方式了。
在RPC的路线演化过程中虽然意外地产生了HTTP REST这个慢慢侵占了RPC大部分应用领地的“异类”,并且导致了一度盛行的XML-RPC的“灭绝”,但同时推动正统RPC技术走向一个新的发展阶段,追求更高的性能及增加对多语言多平台的支持,成为越来越多的开源RPC架构的目标。其典型的代表为Thrift、Avro 等优秀的酸奶的开源框架,这些框架在大数据系统、大型分布式系统及移动互联网应用方面被越来越多的公司使用。
之后,最初参与CORBA的技术专家们打造了延续至今的RPC平台——ZeroC lce。现在,ZeroC Ice已经成为一个很强大的微服务架构平台,很适合作为大型分布式系统、电商系统、电信金融等关键业务系统的基础架构。
RPC技术发展至今,虽然是相对古老的传统技术,却有着其独特的优势,特别是拥有高性能传输及支持高并发请求的绝对优势,使得RPC技术在互联网时代又一次被巨头们所重视。
其中一个典型的代表是Facebook开源的跨语言的RPC架构Thrift。Thrift 于2008年被贡献给Apache,目前支持多达25种编程语言。Thrift 与ZeroC Ice属于COBRA一脉相传的“很正统”的RPC实现方案,使用方式也很类似,即先编写服务接口的IDL文件,然后利用框架提供的编译生成器工具自动生成Server端的骨架代码和客户端的调用代码,最后由程序员填充骨架代码。
另一个典型的代表是谷歌于2015年开源的跨语言的RPC框架——gRPC,gRPC采用的默认的编码机制也是谷歌设计的ProtoBuf。gRPC支持在任意环境下使用,支持物联网、手机、浏览器。支持浏览器这一点很关键,它表明gRPC 的定位及与传统RPC的不同。gRPC没有基于传统的自定义TCP Socket传输通道,而是基于现有的HTTP 2.0!这样看来,gRPC的性能肯定比不过ZeroC Ice、Thrift这些传统RPC,但更通用、直接面向浏览器、取得更大的影响力才是谷歌推出 gRPC的初心。目前用Go开发的分布式系统,比较著名的如Kuberntes、Istio等,都是以gRPC作为分布式通信的接口协议的。
本文给大家讲解的内容是架构解密从分布式到微服务:古老又有生命力的 RPC
下篇文章给大家讲解的是架构解密从分布式到微服务:从 RPC到服务治理框架;觉得文章不错的朋友可以转发此文关注小编;感谢大家的支持!