网络-RPC

网络-RPC

转载声明

本文大量内容系转载自以下文章,有删改,并参考其他文档资料加入了一些内容:

1 RPC原理

1.0 背景

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

  • 单一应用架构
    当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。
    在这里插入图片描述

  • 垂直应用架构
    当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,需要将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的 Web框架(MVC) 是关键。
    在这里插入图片描述

  • 分布式服务架构
    当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的 分布式服务框架(RPC),提供统一的服务是关键。

    例如:各个团队的服务提供方就不要各自实现一套序列化、反序列化、网络框架、连接池、收发线程、超时处理、状态机等“业务之外”的重复技术劳动,造成整体的低效。所以,统一RPC框架来解决提供统一的服务。
    在这里插入图片描述

1.1 简介

RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。

比如两个不同的服务 A、B 部署在两台不同的机器上,那么服务 A 如果想要调用服务 B 中的某个方法该怎么办呢?使用 HTTP请求 当然可以,但是可能会比较慢而且一些优化做的并不好。RPC 的出现就是为了解决这个问题。

1.2 原理

在这里插入图片描述
一个基本的RPC架构里面应该至少包含以下4个组件:

  1. 客户端(Client):服务调用方(服务消费者)
  2. 客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数数据信息打包成网络消息,再通过网络传输发送给服务端
  3. 服务端存根(Server Stub):接收客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理
  4. 服务端(Server):服务的真正提供者

RPC中一次Client到Server的请求流程如下:

  1. 服务消费方(client)调用以本地调用方式调用服务;
  2. client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体,这里就会将要发送的消息进行序列化(Serialize)或者编组(marshal)成二进制的形式;
  3. client stub需要先和服务端建立连接(如TCP,也可以),这个时候就需要寻址,可通过Redis、ZK等服务注册的方式来找到服务地址,并将消息发送到服务端。这就要求服务提供者启动时候就向注册中心注册服务,启动后心跳方式维持注册的节点,停止时注销服务。服务调用方启动时就订阅注册中心的消息并从注册中心获取服务提供者的地址, 当有提供者上线或者下线时,注册中心会告知到调用者;
    在这里插入图片描述
  4. server stub收到消息后进行反序列化解码;
  5. server stub根据解码结果找到并本地调用本地的服务方法;(一般是通过生成代理Proxy去调用,通常会有JDK动态代理、CGLIB动态代理、Javassist生成字节码技术等)
  6. 本地服务执行并将结果返回给server stub;
  7. server stub将返回结果序列化成二进制消息并发送至消费方;
  8. client stub接收到消息,并进行反序列化解码;
  9. 服务调用方得到最终结果。

再以时序图方式看看流程:
在这里插入图片描述

1.3 RPC 解决了什么问题?

让分布式或者微服务系统中不同服务之间的调用像调用本地方法一样简单。

1.4 常见的 RPC 框架总结

  • RMI(JDK自带)
    JDK自带的RPC,有很多局限性,不推荐使用。

  • Dubbo
    Dubbo是 阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。目前 Dubbo 已经成为 Spring Cloud Alibaba 中的官方组件。

  • gRPC
    gRPC是可以在任何环境中运行的现代开源高性能RPC框架。它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,运行状况检查和身份验证。它也适用于分布式计算的最后一英里,以将设备,移动应用程序和浏览器连接到后端服务。

  • Hessian
    Hessian是一个轻量级的remotingonhttp工具,使用简单的方法提供了RMI的功能。相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。

  • Thrift
    Apache Thrift是Facebook开源的跨语言的RPC通信框架,目前已经捐献给Apache基金会管理,由于其跨语言特性和出色的性能,在很多互联网公司得到应用,有能力的公司甚至会基于thrift研发一套分布式服务框架,增加诸如服务注册、服务发现等功能。

1.5 既有 HTTP ,为啥用RPC进行服务调用?

1.5.1 原因

RPC 只是一种概念、一种设计,就是为了解决不同服务之间的调用问题, 它一般会包含有 传输协议 和 序列化协议 这两个。

实现 RPC 的传输协议可以直接建立在 TCP 之上,也可以建立在 HTTP 协议之上。

大部分 RPC 框架都是使用的 TCP 连接(gRPC使用了HTTP2)。

HTTP 和 RPC 都是用于实现服务之间调用的通信协议。它们之间有一些重要的区别,这就是为什么在某些情况下,人们更倾向于使用 RPC 而不是 HTTP。

  • 抽象层次
    • RPC(远程过程调用)是一种更高级别的抽象,它允许调用远程服务器上的函数或方法,就像调用本地函数一样
    • 而 HTTP 是一种基于请求-响应模型的应用层协议,通常用于在 Web 浏览器和 Web 服务器之间传输数据。RPC 提供了一种更自然、更面向对象的方式来实现服务之间的交互。
  • 传输协议
    • HTTP 基于 TCP/IP 协议,
    • 而 RPC 可以支持传输协议,如 TCP、UDP、HTTP 等。这意味着 RPC 可以更灵活地根据应用需求选择合适的传输协议。
  • 性能
    • RPC 通常比 HTTP 更加高效,因为它可以使用多种序列化二进制协议(如 gRPC、Thrift 、Protocol Buffers、Thrift 等),这些技术在序列化和反序列化过程中具有更高的效率和更小的数据大小。)来序列化和反序列化数据,
    • 相比之下,HTTP 通常使用 JSON 或 XML 进行序列化,这些格式相对较大且解析速度较慢。
    • RPC 通常支持长连接,减少了建立和关闭连接的开销。
  • 易用性和更好的封装性
    • RPC 框架通常提供代码生成工具,可以自动生成客户端和服务器端的代码。这使得开发人员可以更专注于实现业务逻辑,而无需关心底层通信细节。
    • 而在使用 HTTP 时,开发人员需要手动处理请求和响应的编码、解码、路由等问题。
  • 错误处理
    • RPC 框架通常提供了更好的错误处理机制,允许在服务之间传递详细的错误信息。
    • 而在 HTTP 中,错误通常用状态码表示,这限制了错误信息的表达能力。
  • 可扩展性
    • RPC 框架通常提供了更多的可扩展性选项,例如服务注册与发现、负载均衡、限流、熔断等功能。这些功能可以帮助构建更加健壮和可维护的服务架构。

尽管 RPC 在某些方面具有优势,但 HTTP 仍然在许多场景下是一个很好的选择,特别是在构建面向公众的 Web 服务时。HTTP 的普及程度和成熟度使得它在许多场景下都能很好地满足需求。在选择使用 HTTP 还是 RPC 时,需要根据具体的应用场景和需求来权衡。

1.5.2 HTTP和TCP使用分析

我们通常谈计算机网络的五层协议的体系结构是指:应用层、传输层、网络层、数据链路层、物理层。

  • 工作在应用层的HTTP
    应用层(application-layer)的任务是通过应用进程间的交互来完成特定网络应用。HTTP 属于应用层协议,它会基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。HTTP协议工作于客户端-服务端架构为上。

    浏览器作为HTTP客户端通过 URL 向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。

    注意:HTTP协议建立在 TCP 协议之上。

  • 工作在传输层的TCP协议
    主要解决数据如何在网络中传输。运输层(transport layer)的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务。相比于UDP,TCP 提供的是面向连接的,可靠的数据传输服务。

  • HTTP 使用的 TCP 协议,和我们自定义的 TCP 协议在报文上的区别
    主要关键就在 HTTP 使用的 TCP 协议,和我们自定义的 TCP 协议在报文上的区别。

    http1.1协议的 TCP 报文包含太多在传输过程中可能无用的信息:

    HTTP/1.0 200 OK
    Content-Type: text/plain
    Content-Length: 137582
    Expires: Thu, 05 Dec 1997 16:00:00 GMT
    Last-Modified: Wed, 5 August 1996 15:55:28 GMT
    Server: Apache 0.84
    
    <html>
     <body>Hello World</body>
    </html>
    

    而使用自定义 TCP 协议进行传输就会避免上面这个问题,极大地减轻了传输数据的开销。 这也就是为什么通常会采用自定义 TCP 协议的 RPC 来进行进行服务调用的真正原因。

    除此之外,成熟的 RPC 框架还提供好了“服务自动注册与发现”、“智能负载均衡”、“可视化的服务治理和运维”、“运行期流量调度”等等功能,这些也算是选择 RPC 进行服务注册和发现的一方面原因吧!

再说一个常见的错误观点

很多文章中还会提到说 HTTP 协议相较于自定义 TCP 报文协议,增加的开销在于连接的建立与断开,但是这个观点已经被否认,下面截取自某乎中一个回答:

首先要否认一点 HTTP 协议相较于自定义 TCP 报文协议,增加的开销在于连接的建立与断开。HTTP 协议是支持连接池复用的,也就是建立一定数量的连接不断开,并不会频繁的创建和销毁连接。二要说的是 HTTP 也可以使用 Protobuf 这种二进制编码协议对内容进行编码,因此二者最大的区别还是在传输协议上。

1.6 RPC怎么保证可靠性

1.7 RPC Server怎么透传内部服务器错误给客户端

1.8 RPC连接中断后应该马上重连还是怎么办

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值