RPC 和 HTTP 理解

news2024/11/25 18:51:05

        网上充斥着各类类似于这样的文章:rpc 比 http 快了多少倍?既然有了 http,为什么还要用 rpc 调用等等。遇到这类文章,说明对 http 和 rpc 是由理解误区的。

  这里再次重复强调一遍,通信协议不是 rpc 最重要的部分,不要被这类回答带偏。如果要了解 rpc 请更多的去了解服务治理(SOA)的一些基本策略,推荐去看看 dubbo 的相关文档。

详解

  rpc是远端过程调用,其调用协议通常包含:传输协议 和 序列化协议

  传输协议

  比如著名的 grpc,它底层使用的是 http2 协议;还有 dubbo 一类的自定义报文的 tcp 协议

  序列化协议

  例如基于文本编码的 json 协议;也有二进制编码的 protobuf、hession 等协议;还有针对 java 高性能、高吞吐量的 kryo 和 ftc 等序列化协议

  因此我理解大部人理解误区的问题应该是:

  为什么要使用自定义 tcp 协议的 rpc 做后端进程通信?

解答

  要解决这个问题就应该搞清楚 http 使用的 tcp 协议,和我们自定义的 tcp 协议在报文上的区别。

  首先要 否认 一点 http 协议相较于 自定义tcp 报文协议,增加的开销在于连接的建立与断开

  第一、http协议是支持连接池复用的,也就是建立一定数量的连接不断开,并不会频繁的创建和销毁连接

  第二、http也可以使用 protobuf 这种二进制编码协议对内容进行编码

  因此二者即 http 和 rpc 最大的区别还是在传输协议上。

  通用定义的http1.1协议的tcp报文包含太多废信息,一个POST协议的格式大致如下

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>

  即使编码协议也就是 body 是使用二进制编码协议,报文元数据也就是header头的键值对却使用了文本编码,非常占字节数。如上图所使用的报文中有效字节数仅仅占约 30%,也就是70%的时间用于传输元数据废编码。当然实际情况下报文内容可能会比这个长,但是报头所占的比例也是非常可观的。

        那么假如我们使用自定义tcp协议的报文如下

  报头占用的字节数也就只有16个byte,极大地精简了传输内容。

  这也就是为什么后端进程间通常会采用 自定义tcp协议 的 rpc 来进行通信的原因。

不单效率那么简单

  所谓的效率优势是针对 http1.1协议 来讲的,http2.0协议 已经优化编码效率问题,像 grpc 这种 rpc 库使用的就是 http2.0协议。这么来说吧,http容器的性能测试单位通常是kqps,自定义tpc协议则通常是以 10kqps 到 100kqps 为基准

  简单来说成熟的 rpc库相对 http容器,更多的是封装了 “服务发现”,"负载均衡",“熔断降级” 一类面向服务的高级特性。可以这么理解,rpc框架是面向服务的更高级的封装。如果把一个http servlet 容器上封装一层服务发现 和 函数代理调用,那它就已经可以做一个rpc框架了。

所以为什么要用rpc调用?

  因为良好的 rpc 调用是 面向服务的封装,针对服务的 可用性 和 效率 等都做了优化。单纯使用http调用则缺少了这些特性。

  可以这样说:用http不是因为它性能好,而是因为它普适,随便一个web容器就能跑起来你的应用。

RPC 底层是怎么实现的

  之前有看过几个帖子,评论区有激烈的争吵,主要围绕两点,具体如下:

  1. HTTP 和 RPC 是同一级别,还是被 RPC 包含?

  2. Restful 也属于 RPC 吗?

  对于以上两个问题,这里用一个图来一一说明:

  上图是一个比较完整的关系图,这时我们发现HTTP(图中蓝色框)出现了两次。

  其中一个是 和 RPC并列的,都是跨应用调用方法的解决方案;

  另一个则是被RPC包含的,是RPC通信过程的可选协议之一。

  因此,第一个问题的答案是都对。看指的是哪一个蓝色框。从题主的提问看,既然题主在纠结这两者,应该是指与RPC并列的蓝色框。

  第二个问题是在问远程过程调用(红色框)是不是包含了Restful(黄色框),这种理解的关键在于对RPC的理解。

  RPC字面理解是"远程过程调用",即在一个应用中调用另一个应用的方法。那Restful是满足的,通过它可以实现在一个应用中调用另一个应用的方法。

  但是,上述理解使得RPC的定义过于宽泛。RPC通常特指在一个应用中调用另一个应用的接口而实现的远程调用,即红色框所指的范围。这样,RPC是不包含Restful的。

  因此,第二个问题的答案是Restful不属于RPC。

  RPC的英文全称是:Remote Procedure Call,翻译为中文叫 “远程过程调用”。其中稍显晦涩的其实就是“过程”,过程其实就是“方法”。所以,可以把RPC理解为“远程方法调用”。

  要了解远程过程调用,那先理解过程调用。非常简单,如下图,就是调用一个方法。这太常见了,不多解释。

   而在分布式系统中,因为每个服务的边界都很小,很有可能调用别的服务提供的方法。这就出现了服务A 调用 服务B 中方法的需求,即远程过程调用。

  要想让服务A 调用 服务B 中的方法,最先想到的就是通过 HTTP 请求实现。是的,这是很常见的,例如 服务B 暴露 Restful接口,然后让 服务A 调用它的接口。基于Restful的调用方式因为可读性好(服务B暴露出的是Restful接口,可读性当然好)而且HTTP请求可以通过各种防火墙,因此非常不错。

  然而,如前面所述,基于Restful的远程过程调用有着明显的缺点,主要是效率低、封装调用复杂。当存在大量的服务间调用时,这些缺点变得更为突出。

  服务A 调用 服务B 的过程是应用间的内部过程,牺牲可读性提升效率、易用性是可取的。基于这种思路,RPC产生了。

  通常,RPC要求在调用方中放置被调用的方法的接口。调用方只要调用了这些接口,就相当于调用了被调用方的实际方法,十分易用。于是,调用方可以像调用内部接口一样调用远程的方法,而不用封装参数名和参数值等操作。  

   那要想实现这个过程该怎么办呢?别急,咱们一步一步来。

  第一、首先,调用方调用的是接口,必须得为接口构造一个假的实现。显然,要使用动态代理。这样,调用方的调用就被动态代理接收到了。

  第二、动态代理接收到调用后,应该想办法调用远程的实际实现。这包括下面几步:

    1. 识别具体要调用的远程方法的 IP、端口

    2. 将调用方法的入参进行序列化

    3. 通过通信将请求发送到远程的方法中

  第三、这样,远程的服务就接收到了调用方的请求。它应该:

    1. 反序列化各个调用参数

    2. 定位到实际要调用的方法,然后输入参数,执行方法

    3. 按照调用的路径返回调用的结果

  整个过程如下所示。

  

   这样,RPC操作就完成了。

  调用方调用内部的一个方法,但是被RPC框架偷梁换柱为远程的一个方法。之间的通信数据可读性不需要好,只需要RPC框架能读懂即可,因此效率可以更高。通常使用UDP或者TCP作为通讯协议,当然也可以使用HTTP。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2035764.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KubeSphere 部署 Kafka 集群实战指南

本文档将详细阐述如何利用 Helm 这一强大的工具&#xff0c;快速而高效地在 K8s 集群上安装并配置一个 Kafka 集群。 实战服务器配置(架构 1:1 复刻小规模生产环境&#xff0c;配置略有不同) 主机名IPCPU内存系统盘数据盘用途ksp-registry192.168.9.904840200Harbor 镜像仓库…

命令行参数环境变量

目录 前言&#xff1a; 命令行参数&#xff1a; 现象&#xff1a; 这些参数的意义&#xff1a; 为什么要这么做&#xff1f; 这些事是谁做的呢&#xff1f; 环境变量 现象&#xff1a; 创建环境变量&#xff1a; 结合程序理解&#xff1a; 前言&#xff1a; 我们在前…

R语言里认识机器学习

下面内容摘录自&#xff1a; 1章2节&#xff1a;关于人工智能、机器学习、统计学连和机器学习、R 与 ChatGPT 的探究-CSDN博客文章浏览阅读1k次。在现代科技发展的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;、统计学、R 编程…

网络通信(TCP/UDP协议 三次握手四次挥手 )

三、TCP协议与UDP协议 1、TCP/IP、TCP、 UDP是什么 TCP/IP协议是一个协议簇&#xff0c;里面包括很多协议的&#xff0c; UDP只是其中的一个&#xff0c; 之所以命名为TCP/IP协议&#xff0c; 因为TCP、 IP协议是两个很重要的协议&#xff0c;就用他两命名了&#xff0c;而TCP…

告别知云单一选择,这些文献翻译工具同样值得信赖!

在翻译领域&#xff0c;知云文献翻译以其专业度和便捷性赢得了众多用户的青睐&#xff0c;但市场上还有许多其他翻译工具同样值得关注。本文将为您推荐几款优秀的翻译工具。 Foxit在线翻译 链接&#xff1a; https://fanyi.pdf365.cn/ Foxit在线翻译以其高效的翻译速度和准…

创建第一个Qt项目

创建第一个QT项目 创建工程名称一般不要有特殊符号&#xff0c;不要有中文 项目工程保存路径可修改&#xff0c;路径不要带中文 Base class中的三个选项 QMainWindow:主窗口类&#xff0c;包括菜单栏、工具栏、状态栏。 QWidget:可以创建一个空白的窗口&#xff0c;是所有界…

嵌入式软件--数据结构与算法 DAY 13

在嵌入式中&#xff0c;对算法的要求不高&#xff0c;但顺序查找和冒泡排序是经典算法&#xff0c;必须掌握。 1.算法定义 算法是一个用于解决特定问题的有限指令序列&#xff08;计算机可以执行的操作&#xff09;。通俗的理解就是可以解决特定问题的方法。 2.时间复杂度 …

手动和torch.nn实现卷积神经网络、空洞卷积、残差网络

一、数据集 1. 分类问题 数据集——车辆分类数据 ⚫输入图片,输出对应的类别 ⚫共1358张车辆图片 ⚫分别属于汽车、客车和货车三类 ⚫汽车:779张 ⚫客车:218张 ⚫货车:360张 ⚫每个类别随机取20-30%当作测试集 ⚫各图片的大小不一,需要将图片拉伸到相同大小 汽车 …

three.js 安装方法、基础简介、创建基础场景

threejs简介 Three.js是一个基于JavaScript编写的开源3D图形库&#xff0c;‌利用WebGL技术在网页上渲染3D图形。‌ 它提供了许多高级功能&#xff0c;‌如几何体、‌纹理、‌光照、‌阴影等&#xff0c;‌使得开发者能够快速创建复杂且逼真的3D场景。‌ threejs提供了丰富的功…

云原生日志Loki

1. Loki简介 1.1 Loki介绍 Loki是 Grafana Labs 团队最新的开源项目&#xff0c;是一个水平可扩展&#xff0c;高可用性&#xff0c;多租户的日志聚合系统。它的设计非常经济高效且易于操作&#xff0c;因为它不会为日志内容编制索引&#xff0c;而是为每个日志流编制一组标签…

关于Vue项目npm快捷键,点击run启动报错,及npm i也报错的解决办法

1.配置idea的npm 2.点击运行按钮 3.结果 分析原因及问题&#xff1a; npm i npm run dev 由于是刚刚从gitlab新拉的前端代码&#xff0c;可能没有用命令install过类似于没有编译过&#xff0c;所以执行一下上面的命令 结果报错如下&#xff1a; F:\tbyf\qjyy\hip-manager-ui&…

SpringBoot整合MyBatis-Plus完整详细版(提供Gitee源码)

前言&#xff1a;本篇文章完整详细介绍了SpringBoot整合MyBatis-Plus的完整过程&#xff0c;这边我的SpringBoot版本是2.4版本、JDK1.8和Maven3.8.1版本&#xff0c;跟着文章一步步走就可以了&#xff0c;MyBatis-Plus整合非常方便&#xff0c;也是现在企业开发中经常会用的一个…

学习笔记第二十四天

1.exec族函数的区别 int exec l(const char *path, const char *arg, ...); int exec l p(const char *file, const char *arg, ...); int exec l e(const char *path, const char *arg,..., char * const envp[]); int exec v(const char *path, char *const argv[]); …

1011 World Cup Betting

题目 解释 题目讲的就是&#xff0c;给你三行数&#xff0c;每一行包含3个浮点小数&#xff0c;让你找到最大的那个小数&#xff0c;然后如果最后的小数是第一个&#xff0c;输出W&#xff0c;是第二个&#xff0c;输出T&#xff0c;是第三个&#xff0c;输出L&#xff0c;最后…

Day37 | 188.买卖股票的最佳时机IV 309.最佳买卖股票时机含冷冻期 714.买卖股票的最佳时机含手续费

语言 Java 188.买卖股票的最佳时机IV 买卖股票的最佳时机IV 题目 给你一个整数数组 prices 和一个整数 k &#xff0c;其中 prices[i] 是某支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说&#xff0c;你最多…

Broken: Gallery靶机复现

靶机设置 靶机设置为NAT模式 靶机IP发现 nmap 192.168.112.0/24 靶机IP为192.168.112.142 目录扫描 dirsearch 192.168.112.142 访问浏览器 发现文件页面 查看后发现都没什么用 getshell hydra -L rockyou.txt -P rockyou.txt 192.168.112.142 ssh 尝试爆破ssh账号密码…

互联网应用主流框架整合【Redis常用技术】

和其他大部分NoSQL不同&#xff0c;Redis是支持事务的&#xff0c;尽管没有数据库那么强大&#xff0c;但非常有用&#xff0c;在某些高并发但又要保证高度一致性的场景下&#xff0c;代替数据库事务非常有效&#xff1b;在Redis的机制中&#xff0c;允许通过流水线一次性发给R…

DATAX自定义KafkaWriter

因为datax目前不支持写入数据到kafka中&#xff0c;因此本文主要介绍如何基于DataX自定义KafkaWriter&#xff0c;用来同步数据到kafka中。本文偏向实战&#xff0c;datax插件开发理论宝典请参考官方文档&#xff1a; https://github.com/alibaba/DataX/blob/master/dataxPlug…

2024年TI杯E题-三子棋游戏装置方案分享-jdk123团队-第二弹 手搓机械臂

第一弹赛题的选择与前期方案的准备 opencv调用摄像头bug的解决 机械臂的组装 采用三个舵机&#xff0c;组成一个三自由度的机械臂。 并且利用电磁吸盘的方式&#xff0c;完成对棋子的抓取工作&#xff0c;后面的事实证明&#xff0c;在预算不足的情况下&#xff0c;队友手搓…

顺序表的实现——数据结构

线性表 文章目录 线性表线性表的定义和基本操作线性表的定义线性表的基本操作 线性表的顺序表示顺序表的定义顺序表的实现——静态分配顺序表的实现——动态分配顺序表的特点 线性表的定义和基本操作 线性表的定义 线性表&#xff08;Linear List&#xff09;的定义 ​ 线性…