计算机网络

一、HTTP

1. GET和POST的区别

1. 数据传输方式:

  • GET: 数据通过 URL 传输,并附加在 URL 后面,以键值对的形式出现,例如 https://www.example.com/index.php?id=123&name=John
  • POST: 数据通过 HTTP 请求体传输,不会显示在 URL 中。

2. 数据大小限制:

  • GET: URL 长度有限制,通常为 2048 个字符,因此 GET 请求传输的数据量有限。
  • POST: 没有数据大小限制,可以传输更大的数据量。

3. 幂等性:

  • GET: 幂等,即多次执行相同的 GET 请求会产生相同的结果
  • POST: 非幂等,即多次执行相同的 POST 请求可能会产生不同的结果,例如提交表单数据。

4. 安全性:

  • GET: 数据暴露在 URL 中,安全性较低
  • POST: 数据隐藏在 HTTP 请求体中,安全性较高

5. 缓存:

  • GET: 可以被浏览器缓存,以便下次访问时更快地加载。
  • POST: 通常不会被缓存。
    总结:
特性GETPOST
数据传输方式URLHTTP 请求体
数据大小限制有限无限制
幂等性幂等非幂等
安全性较低较高
缓存可以缓存通常不会缓存

2. HTTP 缓存技术

举个例子,我们通过浏览器访问某些网站时,如果重复访问同一个页面每次都向服务器发送请求获取数据,这样显然效率和使用体验不是很好,所以浏览器将重复性HTTP请求的数据缓存在本地

HTTP缓存的实现有两种方式,分别是强制缓存协商缓存

强制缓存

强制缓存是浏览器判断缓存数据是否过期,如果未过期则使用缓存数据;是否使用缓存的决定者是浏览器

强缓存是利用下面这两个 HTTP 响应头部(Response Header)字段实现的,它们都用来表示资源在客户端缓存的有效期

  • Cache-Control, 是一个相对时间;
  • Expires,是一个绝对时间;

如果 HTTP 响应头部同时有Cache-ControlExpires 字段的话,Cache-Control 的优先级高于 Expires

Cache-control 选项更多一些,设置更加精细,所以建议使用 Cache-Control 来实现强缓存。具体的实现流程如下:

  • 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 Cache-Control,Cache-Control 中设置了过期时间大小;
  • 浏览器再次请求访问服务器中的该资源时,会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小,来计算出该资源是否过期,如果没有,则使用该缓存,否则重新请求服务器;
  • 服务器再次收到请求后,会再次更新 Response 头部的 Cache-Control

在这里插入图片描述

协商缓存

协商缓存是浏览器向服务器发送请求获取数据,服务器并不响应数据给浏览器,而是返回给浏览器一个响应状态码304,这个状态码的意思是告诉浏览器可以使用本地缓存的数据;是否使用缓存的决定者是服务器

协商缓存是使用HTTP请求的请求头部和响应头部中的字段实现的。

第一种:

  • 请求头部的If-Modified-Since:请求时携带Last-Modified中的时间。

  • 响应头部的Last-Modified:响应数据的最后一次修改时间。

第二种:

  • 请求头部的If-None-Match:请求时携带Etag中的唯一标识。

  • 响应头部的Etag:响应资源的唯一标识。

第一种是基于时间实现的,第二种是基于响应资源的唯一标识实现的;第二种实现方式可以更好的判断资源是否被修改过,从而避免篡改导致不可靠问题。

如果第一次请求数据后,服务器返回的响应头中同时包含了Last-ModifiedEtag两个字段,那么再次请求时请求头也会携带这两个字段的信息,但是Etag的优先级更高。

也就是服务端先会判断 Etag 是否变化了,如果 Etag 有变化就不用在判断 Last-Modified 了,如果 Etag 没有变化,然后再看 Last-Modified

当使用 ETag 字段实现的协商缓存的过程:

  • 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 ETag 唯一标识,这个唯一标识的值是根据当前请求的资源生成的;
  • 当浏览器再次请求访问服务器中的该资源时,首先会先检查强制缓存是否过期:
     如果没有过期,则直接使用本地缓存;
     如果缓存过期了,会在 Request 头部加上 If-None-Match 字段,该字段的值就是ETag唯一标识;
  • 服务器再次收到请求后,会根据请求中的 If-None-Match 值与当前请求的资源生成的唯一标识进行比较:
     如果值相等,则返回 304 Not Modified,不会返回资源;
     如果不相等,则返回 200 状态码和返回资源,并在 Response 头部加上新的 ETag 唯一标识
  • 如果浏览器收到 304 的请求响应状态码,则会从本地缓存中加载资源,否则更新资源。

**为什么 ETag 的优先级更高?**这是因为 ETag 主要能解决 Last-Modified 几个比较难以解决的问题:

  1. 在没有修改文件内容情况下文件的最后修改时间可能也会改变,这会导致客户端认为这文件被改动了,从而重新请求;
  2. 可能有些文件是在秒级以内修改的,If-Modified-Since 能检查到的粒度是秒级的,使用 Etag就能够保证这种需求下客户端在 1 秒内能刷新多次;
  3. 有些服务器不能精确获取文件的最后修改时间

注意,协商缓存这两个字段都需要配合强制缓存中 Cache-Control 字段来使用,只有在未能命中强制缓存的时候,才能发起带有协商缓存字段的请求。

HTTP 缓存流程图

在这里插入图片描述

3. HTTP不同版本比较

图解不同版本的HTTP协议

版本发布日期特性优点缺点
HTTP/0.91991简单,没有版本号、头部信息和消息体简单易用功能有限
HTTP/1.01996更复杂,包括版本号、头部信息和消息体兼容性好效率低下
HTTP/1.11997引入了持久连接、管道化和缓存等功能效率高、可扩展性好复杂度高
HTTP/22015引入了多路复用、头部压缩和服务器推送等功能速度快、效率高兼容性问题
HTTP/32022基于 UDP,引入了更快的速度和更低的延迟速度快、延迟低兼容性问题

HTTP/0.9

  • 非常简单,没有版本号、头部信息和消息体
  • 只能发送 GET 请求
  • 只能返回文本数据

HTTP/1.0

  • 更复杂,包括版本号、头部信息和消息体
  • 支持 GET、POST、HEAD 等请求方法。
  • 支持多种数据类型

HTTP/1.1※

  • 引入了持久连接、管道化和缓存等功能。
  • 提高了效率和可扩展性。
  • 增加了安全性功能。
  • 持久化连接:当浏览器建立一个 TCP 连接时,多个请求都会使用这条连接。(现如今大多数浏览器默认都是开启的)
  • 管道:通过这个管道,浏览器的多个请求可以同时发到服务器,但是服务器的响应只能够一个接着一个的返回

HTTP/2

  • 引入了多路复用、头部压缩和服务器推送等功能。
  • 速度更快、效率更高。
  • 减少了网络流量。
  • 多路复用:在一条连接上,我可以同时发起无数个请求,并且响应可以同时返回
  • 头部压缩:在客户端和服务器端会使用并且维护「首部表」来跟踪和存储之前发送的键值对,对于相同的头部,不必再通过请求发送,只需发送一次
  • 服务器推送:服务器推送是指在客户端请求之前发送数据的机制。如果一个请求是由你的主页发起的,服务器很可能响应主页内容、logo以及样式表,因为它知道客户端会用到这些东西。这相当于在一个 HTML 文档内集合了所有的资源,不过与之相比,服务器推送有一个很大的优势:可以缓存

HTTP/3

  • 基于 UDP,引入了更快的速度和更低的延迟。
  • QUIC (quick UDP internet connections):一种基于UDP的低延迟传输协议。

4. HTTP/1.1

http1.1

优点

  • 简单、灵活和易于扩展、应用广泛和跨平台
  • 长连接、管道、缓存

缺点

HTTP 协议里有优缺点一体的双刃剑,分别是「无状态、明文传输」,同时还有一大缺点「不安全」

1. 无状态双刃剑

  • 无状态的好处,因为服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。

  • 无状态的坏处,既然服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦

例如登录->添加购物车->下单->结算->支付,这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的,每次都要问一遍身份信息。

这样每操作一次,都要验证信息,这样的购物体验还能愉快吗?别问,问就是酸爽!

对于无状态的问题,解法方案有很多种,其中比较简单的方式用 Cookie 技术。

Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态

相当于,在客户端第一次请求后,服务器会下发一个装有客户信息的「小贴纸」,后续客户端请求服务器的时候,带上「小贴纸」,服务器就能认得了了,
在这里插入图片描述
2. 明文传输双刃剑

  • 明文意味着在传输过程中的信息,是可方便阅读的,比如 Wireshark 抓包都可以直接肉眼查看,为我们调试工作带了极大的便利性。

但是这正是这样,HTTP 的所有信息都暴露在了光天化日下,相当于信息裸奔。在传输的漫长的过程中,信息的内容都毫无隐私可言,很容易就能被窃取,如果里面有你的账号密码信息,那你号没了。

3. 不安全

HTTP 比较严重的缺点就是不安全:

  • 通信使用明文(不加密),内容可能会被窃听。比如,账号信息容易泄漏,那你号没了。
  • 不验证通信方的身份,因此有可能遭遇伪装。比如,访问假的淘宝、拼多多,那你钱没了。
  • 无法证明报文的完整性,所以有可能已遭篡改。比如,网页上植入垃圾广告,视觉污染,眼没了。
    HTTP 的安全问题,可以用 HTTPS 的方式解决,也就是通过引入 SSL/TLS 层,使得在安全上达到了极致。

性能

1. 长连接

早期 HTTP/1.0 性能上的一个很大的问题,那就是每发起一个请求,都要新建一次 TCP 连接(三次握手),而且是串行请求,做了无谓的 TCP 连接建立和断开,增加了通信开销。

为了解决上述 TCP 连接问题,HTTP/1.1 提出了长连接的通信方式,也叫持久连接。这种方式的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载

2. 管道网络传输

HTTP/1.1 采用了长连接的方式,这使得管道(pipeline)网络传输成为了可能。

即可在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间
在这里插入图片描述
所以,HTTP/1.1 管道解决了请求的队头阻塞,但是没有解决响应的队头阻塞

3. 队头阻塞

「请求 - 应答」的模式会造成 HTTP 的性能问题。为什么呢?

因为当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一同被阻塞了,会招致客户端一直请求不到数据,这也就是「队头阻塞」,好比上班的路上塞车。

在这里插入图片描述

5. HTTP 与 HTTPS

HTTP 与 HTTPS 有哪些区别?

  • HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输

  • HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。

  • 两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443

  • HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

HTTPS 解决了 HTTP 的哪些问题?

HTTP 由于是明文传输,所以安全上存在以下三个风险:

  • 窃听风险,比如通信链路上可以获取通信内容,用户号容易没。
  • 篡改风险,比如强制植入垃圾广告,视觉污染,用户眼容易瞎。
  • 冒充风险,比如冒充淘宝网站,用户钱容易没。

HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议,可以很好的解决了上述的风险:

  • 信息加密:交互信息无法被窃取,但你的号会因为「自身忘记」账号而没。
  • 校验机制:无法篡改通信内容,篡改了就不能正常显示,但百度「竞价排名」依然可以搜索垃圾广告。
  • 身份证书:证明淘宝是真的淘宝网,但你的钱还是会因为「剁手」而没。

HTTPS 是如何解决上面的三个风险的?

  • 混合加密的方式实现信息的机密性,解决了窃听的风险。
  • 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
  • 将服务器公钥放入到数字证书中,解决了冒充的风险。

1. 混合加密

通过混合加密的方式可以保证信息的机密性,解决了窃听的风险。

在这里插入图片描述

  • 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
  • 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。

采用「混合加密」的方式的原因:

  • 对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换。
  • 非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢。

2. 摘要算法 + 数字签名

为了保证传输的内容不被篡改,我们需要对内容计算出一个「指纹」,然后同内容一起传输给对方。

对方收到后,先是对内容也计算出一个「指纹」,然后跟发送方发送的「指纹」做一个比较,如果「指纹」相同,说明内容没有被篡改,否则就可以判断出内容被篡改了。

那么,在计算机里会用摘要算法(哈希函数)来计算出内容的哈希值,也就是内容的「指纹」,这个哈希值是唯一的,且无法通过哈希值推导出内容
在这里插入图片描述
通过哈希算法可以确保内容不会被篡改,但是并不能保证「内容 + 哈希值」不会被中间人替换,因为这里缺少对客户端收到的消息是否来源于服务端的证明

举个例子,你想向老师请假,一般来说是要求由家长写一份请假理由并签名,老师才能允许你请假。

但是你有模仿你爸爸字迹的能力,你用你爸爸的字迹写了一份请假理由然后签上你爸爸的名字,老师一看到这个请假条,查看字迹和签名,就误以为是你爸爸写的,就会允许你请假。

那作为老师,要如何避免这种情况发生呢?现实生活中的,可以通过电话或视频来确认是否是由父母发出的请假,但是计算机里可没有这种操作。

那为了避免这种情况,计算机里会用非对称加密算法来解决,共有两个密钥:

  • 一个是公钥,这个是可以公开给所有人的;
  • 一个是私钥,这个必须由本人管理,不可泄露。

这两个密钥可以双向加解密的,比如可以用公钥加密内容,然后用私钥解密,也可以用私钥加密内容,公钥解密内容。

流程的不同,意味着目的也不相同:

  • 公钥加密,私钥解密。这个目的是为了保证内容传输的安全,因为被公钥加密的内容,其他人是无法解密的,只有持有私钥的人,才能解密出实际的内容;
  • 私钥加密,公钥解密。这个目的是为了保证消息不会被冒充,因为私钥是不可泄露的,如果公钥能正常解密出私钥加密的内容,就能证明这个消息是来源于持有私钥身份的人发送的。

一般我们不会用非对称加密来加密实际的传输内容,因为非对称加密的计算比较耗费性能的。

所以非对称加密的用途主要在于通过「私钥加密,公钥解密」的方式,来确认消息的身份,我们常说的数字签名算法,就是用的是这种方式,不过私钥加密内容不是内容本身,而是对内容的哈希值加密。

在这里插入图片描述
私钥是由服务端保管,然后服务端会向客户端颁发对应的公钥。如果客户端收到的信息,能被公钥解密,就说明该消息是由服务器发送的。

引入了数字签名算法后,你就无法模仿你爸爸的字迹来请假了,你爸爸手上持有着私钥,你老师持有着公钥。

这样只有用你爸爸手上的私钥才对请假条进行「签名」,老师通过公钥看能不能解出这个「签名」,如果能解出并且确认内容的完整性,就能证明是由你爸爸发起的请假条,这样老师才允许你请假,否则老师就不认。

3. 数字证书

前面我们知道:

  • 可以通过哈希算法来保证消息的完整性;
  • 可以通过数字签名来保证消息的来源可靠性(能确认消息是由持有私钥的一方发送的);
    但是这还远远不够,还缺少身份验证的环节,万一公钥是被伪造的呢?

还是拿请假的例子,虽然你爸爸持有私钥,老师通过是否能用公钥解密来确认这个请假条是不是来源你父亲的。

但是我们还可以自己伪造出一对公私钥啊!

你找了个夜晚,偷偷把老师桌面上和你爸爸配对的公钥,换成了你的公钥,那么下次你在请假的时候,你继续模仿你爸爸的字迹写了个请假条,然后用你的私钥做个了「数字签名」。

但是老师并不知道自己的公钥被你替换过了,所以他还是按照往常一样用公钥解密,由于这个公钥和你的私钥是配对的,老师当然能用这个被替换的公钥解密出来,并且确认了内容的完整性,于是老师就会以为是你父亲写的请假条,又允许你请假了。

好家伙,为了一个请假,真的是斗智斗勇。

后面你的老师和父亲发现了你伪造公私钥的事情后,决定重新商量一个对策来应对你这个臭家伙。

正所谓魔高一丈,道高一尺。

既然伪造公私钥那么随意,所以你爸把他的公钥注册到警察局,警察局用他们自己的私钥对你父亲的公钥做了个数字签名,然后把你爸爸的「个人信息 + 公钥 + 数字签名」打包成一个数字证书,也就是说这个数字证书包含你爸爸的公钥。

这样,你爸爸如果因为家里确实有事要向老师帮你请假的时候,不仅会用自己的私钥对内容进行签名,还会把数字证书给到老师。

老师拿到了数字证书后,首先会去警察局验证这个数字证书是否合法,因为数字证书里有警察局的数字签名,警察局要验证证书合法性的时候,用自己的公钥解密,如果能解密成功,就说明这个数字证书是在警察局注册过的,就认为该数字证书是合法的,然后就会把数字证书里头的公钥(你爸爸的)给到老师。

由于通过警察局验证了数字证书是合法的,那么就能证明这个公钥就是你父亲的,于是老师就可以安心的用这个公钥解密出请假条,如果能解密出,就证明是你爸爸写的请假条。

正是通过了一个权威的机构来证明你爸爸的身份,所以你的伪造公私钥这个小伎俩就没用了。

在计算机里,这个权威的机构就是 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。

数字证书的工作流程,我也画了一张图,方便大家理解:

v

通过数字证书的方式保证服务器公钥的身份,解决冒充的风险。

6. SSL(安全套接层)/TLS(传输层安全)

何时进行 TLS 握手

用户导航到一个使用 HTTPS 的网站,浏览器首先开始查询网站的原始服务器,这时就会发生 TLS 握手。在任何其他通信使用 HTTPS 时(包括 API 调用和 DNS over HTTPS 查询),也会发生 TLS 握手。

通过 TCP 握手打开 TCP 连接后,将发生 TLS 握手。

TLS 握手有哪些步骤?

TLS握手步骤

TLS 握手是由客户端和服务器交换的一系列数据报或消息。TLS 握手涉及多个步骤,因为客户端和服务器要交换完成握手和进行进一步对话所需的信息。

TLS 握手中的确切步骤将根据所使用的密钥交换算法的种类和双方支持的密码套件而有所不同。RSA 密钥交换算法虽然现在被认为不安全,但曾在 1.3 之前的 TLS 版本中使用。大致如下:

  1. “客户端问候(client hello)” 消息: 客户端通过向服务器发送“问候”消息来开始握手。该消息将包含客户端支持的 TLS 版本支持的密码套件,以及称为一串称为“客户端随机数(client random)”的随机字节。
  2. “服务器问候(server hello)”消息: 作为对 client hello 消息的回复,服务器发送一条消息,内含服务器的 SSL 证书服务器选择的密码套件,以及“服务器随机数(server random)”,即由服务器生成的另一串随机字节。
  3. 身份验证: 客户端使用颁发该证书的证书颁发机构验证服务器的 SSL 证书。此举确认服务器是其声称的身份,且客户端正在与该域的实际所有者进行交互。
  4. 预主密钥: 客户端再发送一串随机字节,即“预主密钥(premaster secret)”。预主密钥是使用公钥加密的,只能使用服务器的私钥解密。(客户端从服务器的 SSL 证书中获得公钥。)
  5. 私钥被使用:服务器对预主密钥进行解密
  6. 生成会话密钥:客户端和服务器均使用客户端随机数、服务器随机数和预主密钥生成会话密钥。双方应得到相同的结果。
  7. 客户端就绪:客户端发送一条“已完成”消息,该消息用会话密钥加密。
  8. 服务器就绪:服务器发送一条“已完成”消息,该消息用会话密钥加密。
  9. 实现安全对称加密:已完成握手,并使用会话密钥继续进行通信。

HTTPS 一定安全可靠吗?

客户端通过浏览器向服务端发起 HTTPS 请求时,被「假基站」转发到了一个「中间人服务器」,于是客户端是和「中间人服务器」完成了 TLS 握手,然后这个「中间人服务器」再与真正的服务端完成 TLS 握手。
在这里插入图片描述
但是要发生这种场景是有前提的,前提是用户点击接受了中间人服务器的证书

中间人服务器与客户端在 TLS 握手过程中,实际上发送了自己伪造的证书给浏览器,而这个伪造的证书是能被浏览器(客户端)识别出是非法的,于是就会提醒用户该证书存在问题。
在这里插入图片描述
所以,HTTPS 协议本身到目前为止还是没有任何漏洞的,即使你成功进行中间人攻击,本质上是利用了客户端的漏洞(用户点击继续访问或者被恶意导入伪造的根证书),并不是 HTTPS 不够安全。

为什么抓包工具能截取 HTTPS 数据?

对于 HTTPS 连接来说,中间人要满足以下两点,才能实现真正的明文代理:

  • 中间人,作为客户端与真实服务端建立连接这一步不会有问题,因为服务端不会校验客户端的身份;
  • 中间人,作为服务端与真实客户端建立连接,这里会有客户端信任服务端的问题,也就是服务端必须有对应域名的私钥

中间人要拿到私钥只能通过如下方式:

  • 去网站服务端拿到私钥;
  • 去CA处拿域名签发私钥;
  • 自己签发证书,切要被浏览器信任;

不用解释,抓包工具只能使用第三种方式取得中间人的身份。

使用抓包工具进行 HTTPS 抓包的时候,需要在客户端安装 Fiddler 的根证书,这里实际上起认证中心(CA)的作用。

抓包工具能够抓包的关键是客户端会往系统受信任的根证书列表中导入抓包工具生成的证书,而这个证书会被浏览器信任,也就是抓包工具给自己创建了一个认证中心 CA,客户端拿着中间人签发的证书去中间人自己的 CA 去认证,当然认为这个证书是有效的。

如何避免被中间人抓取数据?

我们要保证自己电脑的安全,不要被病毒乘虚而入,而且也不要点击任何证书非法的网站,这样 HTTPS 数据就不会被中间人截取到了。

当然,我们还可以通过 HTTPS 双向认证来避免这种问题。

一般我们的 HTTPS 是单向认证,客户端只会验证了服务端的身份,但是服务端并不会验证客户端的身份。

如果用了双向认证方式,不仅客户端会验证服务端的身份,而且服务端也会验证客户端的身份。服务端一旦验证到请求自己的客户端为不可信任的,服务端就拒绝继续通信,客户端如果发现服务端为不可信任的,那么也中止通信。

7. HTTP和RPC

HTTP和RPC的区别

  • RPC(即Remote Procedure Call,远程过程调用)主要用于系统内部服务调用传输效率高(基于TCP,报文小),性能消耗低(高效的二进制传输、字节小、序列化耗时少),服务治理方便
  • HTTP(HyperText Transfer Protocol,超文本传输协议)是超文本协议,其包含的信息往往比较臃肿,网关之前一般用http,服务之间能用rpc协议就用rpc协议,除非少部分情况,一些旧的服务它可能只支持http,或者一些node开发团队只能用http,也不太好改成rpc。

1. 传输协议:

  • RPC框架:可以基于HTTP协议,也可以基于TCP协议
  • HTTP框架:基于HTTP协议

从网络协议来说,Http协议与Rpc同属于应用层, 他们的底层都是tcp协议。RPC(即Remote Procedure Call,远程过程调用)和HTTP(HyperText Transfer Protocol,超文本传输协议)他们最本质的区别,就是RPC直接通过自定义TCP协议实现通信,而HTTP服务需要通过HTTP协议,我们都知道HTTP协议是在传输层协议TCP之上的,所以相当于在中间又加了一层,从效率来看的话,RPC当然是要更胜一筹。

2、传输效率:

  • RPC:使用自定义的TCP协议,可以让请求报文体积更小,或者使用HTTP2协议,也可以很好的减小报文体积,提高传输效率
  • HTTP:如果是基于http1.1的协议,请求中会包含很多无用的内容,如果是基于HTTP2.0,那么简单的封装下可以作为一个RPC来使用,这时标准的RPC框架更多的是服务治理。

http协议其实是属于面向桌面浏览器的一个通信协议,对于缓存,幂等或者Cookies相关的方面做了很多的事情。但是对于服务器之间直接的交互,Rpc就能够体现出来他的优势了。自定义协议,减少数据传输:我们大概看一下http协议。请求行,请求头部,请求数据,空行。很明显对于远程调用场景,我们对于请求行的依赖不是特别的强,那么这一部分在我们应用场景下,将会成为负担,但是http协议又是固定的,我们也不可能随便修改协议的格式。所以,通过rpc协议我们可以精简请求的数据,来尽可能少的传输我们的数据。当前,rpc也可以通过http协议来进行传输。

3、性能消耗:

  • RPC:可以基于thrift实现高效的二进制传输
  • HTTP:大部分是基于json实现的,字节大小和序列化耗时都比thrift要更消耗性能

4、负载均衡:

  • RPC:基本自带了负载均衡策略
  • HTTP:需要配置Nginx、HAProxy配置

5、服务治理:(下游服务新增,重启,下线时如何不影响上游调用者)

  • RPC:能做到自动通知,不影响上游
  • HTTP:需要事先通知,如修改NGINX配置。

6、连接:

  • RPC:长连接
  • HTTP:短连接

rpc使用长连接:直接基于socket进行连接,不用每个请求都重新走三次握手的流程

RPC框架

gRPC初探——概念介绍以及如何构建一个简单的gRPC服务
在这里插入图片描述
一个 RPC 的核心功能主要有 5 个部分组成,分别是:客户端客户端 Stub网络传输模块服务端 Stub、服务端等。

下面分别介绍核心 RPC 框架的重要组成:

  • 客户端(Client):服务调用方。
  • 客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数数据信息打包成网络消息,再通过网络传输发送给服务端。
  • 服务端存根(Server Stub):接收客户端发送过来的请求消息并进行解包,然后再调用本地服务进行处理。
  • 服务端(Server):服务的真正提供者。
  • Network Service:底层传输,可以是 TCP 或 HTTP。

一次 RPC 调用流程如下:

  1. 服务消费者(Client 客户端)通过本地调用的方式调用服务。
  2. 客户端存根(Client Stub)接收到调用请求后负责将方法、入参等信息序列化(组装)成能够进行网络传输的消息体。
  3. 客户端存根(Client Stub)找到远程的服务地址,并且将消息通过网络发送给服务端。
  4. 服务端存根(Server Stub)收到消息后进行解码(反序列化操作)。
  5. 服务端存根(Server Stub)根据解码结果调用本地的服务进行相关处理
  6. 服务端(Server)本地服务业务处理。
  7. 处理结果返回给服务端存根(Server Stub)。
  8. 服务端存根(Server Stub)序列化结果。
  9. 服务端存根(Server Stub)将结果通过网络发送至消费方。
  10. 客户端存根(Client Stub)接收到消息,并进行解码(反序列化)。
  11. 服务消费方得到最终结果。

8. WebSocket

平时我们打开网页,比如购物网站某宝。都是点一下「列表商品」,跳转一下网页就到了「商品详情」。

从 HTTP 协议的角度来看,就是点一下网页上的某个按钮,前端发一次 HTTP请 求,网站返回一次 HTTP 响应。这种由客户端主动请求,服务器响应的方式也满足大部分网页的功能场景。

但有没有发现,这种情况下,服务器从来就「不会主动」给客户端发一次消息

详情见:
WebSocket 理论+实操

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值