前言
计算机网络是我们工作中经常要打交道的东西,无论是浏览器与服务端通讯,或是通过ngnix进行转发通信,当然也是面试官最喜欢提问的一块知识点。所以我们必须对网络中部分知识点了如指掌,才能更好的应对工作中复杂的业务场景。
HTTP协议
问题频率:🌟🌟🌟🌟🌟
HTTP协议位于TCP/IP四层模型的应用层,是计算机网络中的重中之重,必须十分熟悉。
Q:什么是HTTP协议?有什么作用?
HTTP(Hyper Text Transfer Protocol)超文本传输协议,是一个控制点对点传输的规范协议。可以传输文本,但不局限于文字,可以是图片、视频、音频等多种格式。
Q:HTTP协议的特性?
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有 GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快
- 灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由
Content-Type加以标记。 - 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- 无状态:HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
Q:HTTP1.0、HTTP1.1、HTTP2.0区别?
这里需要分开讲解每个版本新增的特性。
HTTP1.0
- 文件格式不再局限于
ASCII编码,不光是HTML还有JS、图片、音频和视频。 - 还引入HTTP请求头和响应头(accept-language,expires等)
- 同时也引入了状态码(200,300,400等)
- 为了减轻服务器压力,还引入了
cache(缓存)机制 - 也新增了User-Agent(用户代理)请求头字段
User-Agent请求头有什么作用?主要是为了作为一个浏览器的标识,用来告诉服务器是用什么工具来请求的。比如说可以用来识别是否是爬虫工具,防止页面被爬取。
HTTP1.1
HTTP1.1是目前使用最广泛的协议,所以会更详细的进行介绍,也是需要重点掌握的。
改进持久链接
一个TCP链接可以传输多个HTTP请求,只要不断开链接,TCP会一直保持。持久链接是默认开启的(Connection:keep-alive),如果想要关闭,在请求头加上Connection:close。对于同一域名,默认允许建立6个TCP链接,此时如果再想通信,必须等之前通信完成(队头阻塞)。
Q:有哪些优缺点?
优点:持久链接不需要每次传输完成就断开,减少请求时间。对于频繁请求是适合长链接的。
缺点:对于服务端来说,如果每个链接都需要长连接那么一旦用户量巨大,那么服务器是扛不住的。所以需要选择性的使用长连接,一旦用户长时间不操作就要主动的去关闭链接。
不成熟的管线化
试图用管线化的技术来解决对头阻塞的问题,但因为各种原因,被厂商放弃了。并且只有幂等请求才支持管线化。
Q:什么是管线化?
在上一次请求等待响应的同时,发送下一个请求。只不过服务端还是按照发送请求的顺序处理,客户端还是按照发送请求的顺序接受(先进先出的队列)。
Q:什么是队头阻塞?
如果上一个请求非常耗时,下一个请求必须等待。
Q:什么是幂等请求?
无论请求多少次都会存在相同请求结果的请求都是幂等请求。比如GET、DELETE、HEAD、OPTIONS。不是幂等请求有POST、PATCH。
Q:为什么一定要是幂等才支持管线化?
因为幂等请求不要求到达顺序,可以每次都不一样但是返回的结果都会相同。如果不是幂等那么返回结果会跟请求次序有关。
增加对虚拟主机的支持
每个虚拟主机都有自己的域名,这些单独的域名共用一个IP地址。请求头中增加了Host字段,表示当前域名的地址。
增加对动态生成内容的支持
1.0需要在响应头中增加Content-Length来标识数据的大小。
随着服务器端的发展、很多页面的内容是动态生成的,传输数据并不知道最终的数据大小。导致双方传输时,不知道何时会接受完成数据。
1.1引入了分块传输来解决。服务器将数据分割成若干个大小不同的数据块。每个数据块头部会附上下一个数据块的长度,正文是实际内容。最后使用一个长度为0的数据块标识完成。
使用Transfer-Encoding:chunked这个字段。
HTTP2.0
多路复用
一个域名只使用一个 TCP 长连接和消除队头阻塞问题。通过引入二进制帧层,实现了 HTTP 的多路复用技术。二进制帧层,是一个基于传输层和应用层之间的分层。
2.0中引入了新的编码机制,所有传输的数据都会被分割,采用二进制编码。
帧(frame)和流(stream)是非常重要的概念。
帧是最小的数据单位,每个帧会标识属于哪个流。流由多个帧组成数据流。
一个TCP链接中可以存在多条流,也就是说可以发送多个请求。然后对端可以根据帧的标识知道属于哪个请求。通过这个技术可以避免队头阻塞。
Header压缩
使用HPACK压缩格式对传输的header进行编码,减少了header的大小。并在两端维护了索引表,用于记录出现过的header,后面在传输过程就可以传输记录过的header键名。
HPACK压缩
静态索引表:提前定义好的固定的几十个值,当遇到不在静态表中的会加入到动态表。
动态索引表:动态表是一个先进先出的队列维护有限空间的表,里面同样维护的是与头部对应的索引。每个动态表只针对一个连接,下次同名的值就可能会在找到索引并替换掉头部。
服务端PUSH
在HTTP/2中,服务端可以在客户端某个请求后,主动推送其他资源。用于提升首屏加载速度。浏览器有权选择是否接受。浏览器发送RST_STREAM帧可以选择拒收。
设置请求的优先级
让某些重要的数据优先被服务器处理并返回。
三种设置方式:
- 父级数据流(Parent Stream):这个数据流是一个“依赖”资源或者应该在之后被传递的数据流。有一个所有数据流共享的虚拟
root stream 0。 - 权重(Weight):1到256之间的数字,用于标识在多个数据流共享连接时分配给此数据流的带宽量。带宽是相对于所有其他活动的数据流的权重分配的,而不是绝对值。
- 独占位(Exclusive bit):一个标志,表示应该在不与任何其他数据流共享带宽的情况下下载