RPC定义


  RPC(Remote Procedure Call)全称远程过程调用,它指的是通过网络,我们可以实现客户端调用远程服务端的函数并得到返回结果。这个过程就像在本地电脑上运行该函数一样,只不过系统本身隐藏了发送的过程和细节。

待解决的问题


  (1)既然是远程调用服务端的服务,这就意味着服务端必须知道客户端传递过来函数名、参数名、以及表示方法的意思。这就引出了其中一个问题就是协议约定问题,在客户端和服务器进行服务调用之前,我们需要规定参数所代表的意思,怎么划分边界等等。

  (2)客户端和服务端通过网络进行调用,而在网络中会存在错误、重传、丢包等问题,这些问题我们统称为传输问题。怎么解决这些问题也成为服务是否能实现的关键问题。

  (3)服务发现问题,客户端怎么知道哪些服务可用?以及服务的端口号?这样可以避免对不可用的服务和错误的端口进行请求的时间浪费。

  对于上面的问题,不同的人有不同的解决办法。后来一个叫Nelson的人写了一片论文来定义RPC问题的解决方式和框架。  

  从上图我们可以看到,在客户端中,当用户进行本地调用的时候,会将参数等数据传递给本地的Stub,Stub将参数封装成双方协议规定的模式,然后发送给PRCRuntime模块,该模块主要的任务是进行网络任务,将封装好的参数发送出去,在其中并处理其他会出现的网络异常情况。服务端的PRCRuntime在接收到请求之后将数据传递给Stub模块对数据按照约定的格式进行解封,然后按照客户端的意思调用相应的函数得到结果执行同样的流程进行发送。

RPC的早期(经典)应用


  RPC最早的应用是在NFS(网络文件系统)中,在这个文件系统中我们需要启动两个服务端,一个是mount(挂载文件路径),一个是nfsd(读写文件)。 NFS主要作用是我们可以像操作本地文件一样操作远程服务端上文件的读写。其架构图如下:

  在图中XDR(External Data Representation ,外部数据表示法)进行的是像Stub的工作,对数据按照协议进行相应的封装和解封(压缩成二进制)。例如下图:

  socket进行数据网络的传输,当然这不是简单的socket编程,这里还包含了对于异常的处理,例如超时,重试等问题。这里有一个比较出名的RPC状态转换图。可以看出对应不同的状态有相应的处理方式。

  对于服务发现问题,在NFS中通过portmapper实现的。portmapper 会启动在一个众所周知的端口上,RPC 程序由于是用户自己写的,会监听在一个随机端口上,但是 RPC 程序启动的时候,会向 portmapper 注册。客户端要访问 RPC 服务端这个程序的时候,首先查询 portmapper,获取 RPC 服务端程序的随机端口,然后向这个随机端口建立连接,开始 RPC 调用。从图中可以看出,mount 命令的 RPC 调用,就是这样实现的。

  NFS存在的缺点:(1) 需要双方的压缩格式完全一致,多一位,少一位都可能造成无法解压缩。这一点可以用传输层的可靠性以及加入校验值等方式(冗余检验码)来减少传输过程中的差错。(2) 协议修改不灵活,如果不是传输过程中造成的差错,而是客户端添加或者删除了某些字段或者服务端添加或者删除了字段,而双方没有及时通知,就会造成解压缩不成功。(3)版本的问题,比如在服务端提供一个服务,参数的格式是版本一的,因为其中一个客户端需要对服务多加一个字段,如果服务端加上这一个字段,这会导致所有的客户端都必须加上这个字段。

基于XML的SOAP协议


  在上面NFC的系统中网络传输这块使用的是二进制形式进行传输,并且参数的封装都是严格按照描述文件进行封装的,可读性也比较差。那既然这样我们不采用二进制的形式进行传输,使用文本形式。比如xml格式。一个比较著名的通信协议SOAP(Simple Object Access Protocol,简单对象访问协议)就是使用XML编写请求和回复,使用HTTP进行传输来解决传输问题。例如下面HTTP的请求头的格式,表示传输一个格式为application/soap+xml的XML文件给www.test.com。

POST /purchaseOrder HTTP/1.1
Host: www.test.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn

  这是application/soap+xml的文件内容

 <?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:Header>
<m:Trans xmlns:m="http://www.w3schools.com/transaction/"
soap:mustUnderstand="1">1234
</m:Trans>
</soap:Header>
<soap:Body xmlns:m="http://www.test.com/perchaseOrder">
<m:purchaseOrder">
<order>
<date>2018-07-01</date>
<className> SOAP </className>
<Author> GGG </Author>
</order>
</m:purchaseOrder>
</soap:Body>
</soap:Envelope>

  协议约定问题:在这个过程中我们使用一种叫做Web服务描述语言,WSDL(Web Service Description Languages)也是一个XML文件。服务端对应的WSDL描述文件比较复杂,我们一般可以使用工具进行自动生成。然后客户端根据描述文件进行调用,这里一般的WSDL文件对于客户端的使用者来说晦涩难懂,同时也有相应的工具生成相应的Stub程序来进行协议的封装,让客户端直接调用。

  服务发现问题:在SOAP中有一个UDDI(Universal Description, Discovery, and Integration,统一描述、发现和集成协议)。它其实是一个注册中心,服务提供方可以将上面的 WSDL 描述文件,发布到这个注册中心,注册完毕后,服务使用方可以查找到服务的描述,封装为本地的客户端进行调用。

  缺点:基于XML的SOAP协议虽然使用了文本形式,但是WSDL对于用户来说还是太复杂,对于用户来说并不是很友好。另外,不管是SOAP还是NFS系统,服务端都需要记录不同客户端的状态,这样的情况下如果客户端数目不是很多还能承受,但是一旦客户端数目比较大的时候服务器的负担就会大大增加。

基于JSON的RESTful接口协议


  RESTful指的是一种架构风格,同时也包含API的设计规范。他是由Fielding(HTTP协议的制定者)的博士论文《Architectural Styles and the Design of Network-based Software Architectures》(构风格与基于网络的软件架构设计)所提出来的。他在文中地论证了一个互联网应用应该有的设计要点,而这些设计要点成为后来我们能看到的所有高并发应用设计都必须要考虑的问题,再加上 REST API 比较简单直接,所以后来几乎成为互联网应用的标准接口。

  传输协议问题:RESTful使用HTTP协议进行传输JSON序列化的数据,另外在HTTP中有相应操作的动词。例如GET、POST、DELETE等,来表示对相应的组员的对应操作。

  协议约定问题:不同于SOAP协议服务端需要存储客户端的状态信息,RESTful采用客户端自己管理自己的状态,当需要请求时,客户端端带上必要的信息对服务器端相应的数据进行请求。这就是所谓的无状态服务,其实是服务端维护资源的状态,客户端维护会话的状态。对于服务端来讲,只有资源的状态改变了,客户端才调用 POST、PUT、DELETE 方法来找我;如果资源的状态没变,只是客户端的状态变了,就不用告诉我了,对于我来说都是统一的 GET。按照这种思路,对于 API 的设计,就慢慢变成了以资源为核心,而非以过程为核心。也就是说,客户端只要告诉服务端你想让资源状态最终变成什么样就可以了,而不用告诉我过程,不用告诉我动作。另外,这种 API 的设计需要实现幂等,因为网络不稳定,就会经常出错进行重试,但是一旦重试,就会存在幂等的问题,意思就是说同一个调用,多次调用的结果应该一样,不能一次支付调用,因为调用三次变成了支付三次。也不能一次扣减库存,调用了三次,就扣减三次库存。

  服务发现问题:使用的是Eureka, 他是Netflix开发的服务发现框架,本身是一个基于REST的服务,用于达到负载均衡和中间层服务故障转移的目的。Eureka包含两个组件:Eureka Server和Eureka Client。Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。

  

【RPC】综述的更多相关文章

  1. rpc框架之gRPC 学习 - hello world

    grpc是google在github于2015年开源的一款RPC框架,虽然protobuf很早google就开源了,但是google一直没推出正式的开源框架,导致github上基于protobuf的r ...

  2. 网络协议 19 - RPC协议综述:远在天边近在眼前

    [前五篇]系列文章传送门: 网络协议 14 - 流媒体协议:要说爱你不容易 网络协议 15 - P2P 协议:小种子大学问 网络协议 16 - DNS 协议:网络世界的地址簿 网络协议 17 - HT ...

  3. 网络协议 19 - RPC协议综述

    这几年微服务很火,想必各位博友或多或少的都接触过.微服务概念中, 各服务间的相互调用是不可或缺的一环.你知道微服务之间是通过什么方式相互调用的吗?     你可能说,这还不简单,用 socket 呗. ...

  4. Hadoop RPC

    hadoop rpc机制 && 将avro引入hadoop rpc机制初探 1 RPC RPC(Remote Procedure Call)--远程过程调用,它是一种通过网络从远程计算 ...

  5. 网络协议 20 - RPC 协议(上)- 基于XML的SOAP协议

    [前五篇]系列文章传送门: 网络协议 15 - P2P 协议:小种子大学问 网络协议 16 - DNS 协议:网络世界的地址簿 网络协议 17 - HTTPDNS:私人定制的 DNS 服务 网络协议 ...

  6. [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器

    [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 目录 [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 0x0 ...

  7. [源码解析] PyTorch 分布式(17) --- 结合DDP和分布式 RPC 框架

    [源码解析] PyTorch 分布式(17) --- 结合DDP和分布式 RPC 框架 目录 [源码解析] PyTorch 分布式(17) --- 结合DDP和分布式 RPC 框架 0x00 摘要 0 ...

  8. [源码解析] PyTorch 分布式(18) --- 使用 RPC 的分布式管道并行

    [源码解析] PyTorch 分布式(18) --- 使用 RPC 的分布式管道并行 目录 [源码解析] PyTorch 分布式(18) --- 使用 RPC 的分布式管道并行 0x00 摘要 0x0 ...

  9. 从RPC开始(一)

    这是一篇关于纯C++RPC框架的文章.所以,我们先看看,我们有什么? 1.一个什么都能干的C++.(前提是,你什么都干了) 2.原始的Socket接口,还是C API.还得自己去二次封装... 3.C ...

随机推荐

  1. css学习_css三大特性

    css三大特性 1.层叠性(就近原则) 2.继承性(和文字有关的会继承) 3.优先级   (权重问题) 权重:0,0,0,0 0001 ---标签选择器(注意:即使有20个标签选择器也不会比一个伪类选 ...

  2. express+gulp+gulp-nodemon+browser-sync自动刷新

    express自动生成项目.不在赘述 1.在项目根目录下新建终端,依次运行如下命令 npm install gulp --save-dev npm install gulp-nodemon --sav ...

  3. 【编译原理】c++实现自上而下语法分析器

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...

  4. mysql缓冲

  5. Java之旅_高级教程_实例_打印图形

    1.打印菱形 public class MainClass{ public static void main(String[] args){ printStar(10); } public stati ...

  6. 使用U盘为虚拟机安装系统

    前提:使用虚拟机安装WIN8系统时,由于WIN8镜像文件大于4G无法使用虚拟安装,所以使用U盘安装. 1.装有U盘启动的WINPe系统 (1)下载 老毛桃U盘启动盘制作工具 (2)U盘清空 2.虚拟机 ...

  7. Bloom Filter 数据结构去重

    Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合. Bloom Filter的这种高效是有一定代价的:在判断一个元素是否属于 ...

  8. linux配置IP访问权限

    允许访问vi /etc/hosts.allow添加(可以添加多行,其中“:allow”可以省率)sshd:192.168.81.*:allow                     #表示192.1 ...

  9. 理解Hbase和BigTable(转)

    add by zhj: 这篇文章写的通俗易懂,介绍了HBase最重要的几点特性. 英文原文:https://dzone.com/articles/understanding-hbase-and-big ...

  10. 简单的document操作

    1.新增商品:新建文档,建立索引PUT /index/type/id{ "json数据"}例如:PUT /ecommerce/product/1{ "name" ...