HTTP
HTTP(Hypertext Transfer Protocol,超文本传输协议)是一种用于传输超文本数据(例如网页、图片、视频等)的应用层协议。它是基于客户端-服务器模型的协议,通常在Web浏览器和Web服务器之间进行通信,用于请求和传输Web页面、图像、视频、音频和其他资源。
HTTP 特点
- 简单性: HTTP协议使用简单明了的文本格式进行通信,易于理解和实现。它由请求方法、请求URI、协议版本、请求头部字段和消息主体组成,请求和响应消息之间使用空行分隔。
- 无连接性: 每个HTTP请求-响应周期都是独立的,即客户端发起一个请求,服务器返回一个响应后,连接就会关闭,不会保持连接状态,这样可以减少服务器的资源占用。
- 无状态性: HTTP协议是无状态的,即服务器不会保持客户端的任何状态信息,每个请求都是独立的,服务器无法区分两个请求是否来自同一个客户端。为了解决这个问题,HTTP使用了Cookie和Session等机制来管理状态信息。
- 灵活性: HTTP协议允许传输任意类型的数据,不仅限于文本、图像和音频等媒体类型,还可以传输JSON、XML等数据格式。
HTTP 报文组成
HTTP报文由请求报文和响应报文组成,它们的结构类似,都包括三个部分:起始行、首部字段(Header)和消息主体(Body)。
下面是每个部分的具体组成:
- 请求行(Start Line)
- 对于请求报文,起始行包括请求方法、请求URI和HTTP协议版本,例如:GET /index.html HTTP/1.1
- 对于响应报文,起始行包括HTTP协议版本、状态码和状态消息,例如:HTTP/1.1 200 OK
- 首部字段(Header)
- 首部字段包括多个键值对,每个键值对由字段名和字段值组成,用冒号分隔,例如:Content-Type: text/html
- 首部字段可以有多个,用于描述消息的各种属性和特征,例如:Content-Length、Content-Type、Cache-Control等
- 消息主体(Body)
- 消息主体是可选的,用于承载HTTP请求或响应的具体内容,例如网页、图片、视频等。
- 对于请求报文,消息主体通常用于传递客户端提交的数据,如表单数据或上传的文件。
- 对于响应报文,消息主体通常包含服务器返回的数据,如网页内容或文件内容。
HTTP 通信过程
HTTP协议的通信流程通常包括以下步骤:
- 建立连接: 客户端通过TCP连接与服务器建立连接,通常使用默认端口80进行通信。
- 发送请求: 客户端向服务器发送HTTP请求,请求消息包括请求行(请求方法、请求URI、协议版本)、请求头部和请求主体。
- 处理请求: 服务器接收到请求后,根据请求的内容进行处理,通常是读取请求的资源并生成响应。
- 发送响应: 服务器向客户端发送HTTP响应,响应消息包括状态行(协议版本、状态码、状态消息)、响应头部和响应主体。
- 关闭连接: 客户端和服务器之间的通信结束后,连接关闭,释放相关资源。
HTTP协议在Web应用中扮演着至关重要的角色,它是现代互联网通信的基础,为用户提供了快速、安全和可靠的网络服务。
HTTP 各个版本对比
- HTTP/1.0
- 支持GET、POST等多种请求方法,引入了请求头和响应头。
- 支持状态码、缓存机制和连接保持等特性。
- 连接无法复用,完成即断开
- 重新慢启动和三次握手
- HTTP/1.1
- 引入了持久连接、管道化(pipelining)、分块传输编码(chunked transfer encoding)等性能优化特性。
- 长连接(keep-alive): 一个TCP连接可以复用,发起多个请求
- 管线化(pipeline): 若干个请求排队,串行发起,会导致线头阻塞,导致请求间相互影响
- 新增 host 字段
- cache 缓存
- cache-control
- expires
- if-Modified-since/Last-Modified
- if-None-Match/ Etag
- HTTP/2
- 使用二进制格式传输数据,减少了头部大小,提高了传输效率。
- 多路复用(多个连接并行处理)
- 首部压缩(首部进行 hash 缓存到本地和服务端,减少带宽)
- 服务端推送(静态资源由服务端解析并推送)
- HTTP/3
- 尚未正式发布,目前处于草案阶段。
- 使用QUIC协议替代TCP来传输数据,提高了连接的建立速度和网络抗干扰能力。
- 使用UDP协议代替TCP,引入了0-RTT握手和快速握手等机制,进一步提高了性能。
QUIC 协议
QUIC(Quick UDP Internet Connections)是一种基于UDP的新一代传输协议,旨在提供更快的连接建立和更可靠的数据传输,特别是在高丢包和高延迟网络环境下。
QUIC的主要特点包括:
- 减少连接延迟: QUIC采用0-RTT(零往返时间)握手机制,允许在客户端和服务器之间建立连接时发送数据,从而减少了连接建立的延迟。
- 多路复用: QUIC支持多路复用(Multiplexing),允许在单个连接上同时发送多个数据流,避免了TCP的队头阻塞问题,提高了带宽利用率。
- 头部压缩: QUIC使用类似于HTTP/2的头部压缩算法,减小了头部的大小,节省了带宽和传输延迟。
- 连接迁移: QUIC允许连接在客户端和服务器之间切换网络地址,例如从WiFi切换到移动网络,而无需重新建立连接。
- 零等待恢复: QUIC在断开连接后可以更快地恢复连接,避免了TCP的慢启动过程。
- 安全性: QUIC内置了加密机制,所有的通信都是加密的,提高了数据传输的安全性和隐私保护。
QUIC协议的设计目标是在提供更快速、更可靠的连接的同时,兼顾了安全性和可用性。它可以被用于HTTP/3等应用层协议之上,取代传统的TCP协议,提供更好的性能和用户体验。目前,QUIC协议已经被广泛部署在Google服务(如Gmail、YouTube)等产品中,并正在逐渐得到其他互联网服务提供商的支持和采用。
Q & A
1. http2 实现了多路复用,http 1.x 为什么不能多路复用呢?
HTTP/1.x 协议不能实现多路复用主要是因为它是基于单个TCP连接的。http/1.1 是基于文本分割解析的协议,发送报文的时候,没有序号,如果多路复用,无法保证报文的顺序。
这导致了以下几个问题:
- 队头阻塞(Head-of-line Blocking): 在HTTP/1.x 中,如果一个请求的响应数据因为某种原因(比如网络延迟、请求处理时间长等)被阻塞,那么在同一个TCP连接上的后续请求也会被阻塞,即使它们可以独立并行处理。
- 连接消耗: 每个TCP连接都需要经历三次握手和四次挥手的过程,这会消耗额外的时间和资源。在高并发的情况下,频繁地创建和销毁连接会增加服务器的负载和延迟。
- 头部冗余: 在每个HTTP请求和响应中,都包含一些相同的头部字段(如Host、User-Agent等),这些字段的内容在每个请求中都是重复的,导致了不必要的带宽浪费。
http 2.0 则使用二进制分帧传输,将数据分割为一块块,每一块都对应唯一的序号,因此,可以实现多路复用。
HTTP/2 协议通过引入了多路复用(Multiplexing)机制来解决了这些问题。在HTTP/2 中,客户端和服务器之间只需要建立一个TCP连接,所有的请求和响应都可以在这个连接上并行传输,每个请求都有一个唯一的标识符来区分。这样就避免了队头阻塞问题,提高了网络的利用率,减少了连接的消耗,并且通过头部压缩减小了数据传输的开销。因此,HTTP/2 可以更高效地利用网络资源,提供更快速和可靠的数据传输。
2. http/1.1 管线化
HTTP/1.1 的管线化(pipelining)是一种试图解决队头阻塞问题的机制,它允许客户端在没有等待服务器响应的情况下发送多个请求。具体来说,管线化允许客户端在单个TCP连接上连续发送多个HTTP请求,而不必等待之前的请求得到响应。
管线化的工作流程如下:
- 客户端发送多个请求: 客户端在单个TCP连接上按顺序发送多个HTTP请求,而无需等待前一个请求的响应。
- 服务器处理请求: 服务器收到这些请求后,按照接收顺序逐个处理请求,并生成对应的响应。
- 响应返回给客户端: 服务器将响应按顺序发送给客户端。
- 客户端解析响应: 客户端按照请求的顺序接收响应,并解析处理每个响应。
虽然管线化能够在一定程度上提高HTTP/1.1的性能,但它并没有解决所有的队头阻塞问题,因为在某些情况下,服务器仍然需要按照请求的接收顺序来发送响应。如果前一个请求的处理时间过长,会导致后续请求的响应被阻塞,从而降低了性能。
3. keep-alive 理解
HTTP Keep-Alive 是一种持久连接的机制,它允许客户端和服务器在单个 TCP 连接上发送和接收多个 HTTP 请求和响应,而不必为每个请求/响应对建立和关闭一个新的 TCP 连接。这样可以减少连接建立和关闭的开销,提高网络性能和资源利用率。
在使用 HTTP Keep-Alive 时,客户端和服务器在响应头部中使用 Connection: keep-alive 字段来表明它们支持持久连接。当服务器收到一个请求并发送响应后,它并不会立即关闭连接,而是在响应头部中指定 Connection: keep-alive,告诉客户端保持连接打开。
客户端收到带有 Connection: keep-alive 的响应后,可以继续在同一个 TCP 连接上发送新的请求,而无需重新建立连接。如果在一段时间内没有新的请求发送,连接可能会超时并关闭,这个超时时间通常由服务器端配置。
HTTP Keep-Alive 的优点包括:
- 减少延迟: 不需要为每个请求建立新的 TCP 连接,避免了 TCP 连接的建立和关闭延迟,提高了响应速度。
- 减少资源消耗: 减少了服务器端和客户端的资源消耗,例如 CPU 和内存资源,提高了服务器的并发处理能力。
- 提高网络性能: 通过减少 TCP 连接的数量,减少了网络拥塞和带宽占用,提高了网络的整体性能。
需要注意的是,虽然 HTTP Keep-Alive 可以提高性能,但如果服务器端配置的 Keep-Alive 超时时间设置过短,可能会导致连接频繁断开,反而影响性能。因此,在实际应用中需要合理配置 Keep-Alive 的超时时间,以平衡性能和资源消耗。
4. http/1.1 存在哪些效率问题
- 队头阻塞(Head-of-line Blocking): 在 HTTP/1.1 中,由于每个请求都需要在单个 TCP 连接上依次发送和接收,如果一个请求的响应数据因为某种原因(如网络延迟、请求处理时间长等)被阻塞,那么在同一个连接上的后续请求也会被阻塞,导致了队头阻塞问题。这导致了页面加载速度受限于前面请求的响应速度。
- 多次连接建立和关闭: HTTP/1.1 每次请求都需要新建一个 TCP 连接,并在请求完成后立即关闭连接,这样的连接管理方式会增加网络的延迟和消耗,尤其是在高并发的情况下。频繁的连接建立和关闭也增加了服务器端和客户端的负载。
- 头部冗余: 在 HTTP/1.1 中,每个请求和响应都需要携带一些相同的头部字段(如 Host、User-Agent 等),这些字段的内容在每个请求中都是重复的,导致了不必要的带宽浪费。特别是在包含大量小型资源的页面中,头部字段所占用的比例可能会显著增加。
- 资源阻塞: 在 HTTP/1.1 中,同一个域名下的并发请求数量受到限制(通常是 6-8 个),如果页面中有大量的资源需要加载(如图片、CSS、JS 文件等),可能会导致部分资源被阻塞,延长了页面加载时间。
- 无法充分利用带宽: HTTP/1.1 中每个请求都是按顺序进行发送和接收的,即使是可并行下载的资源也需要等待前面请求的响应完成后才能发送,导致了无法充分利用网络带宽的问题。
这些效率问题限制了 HTTP/1.1 在高性能、高并发场景下的表现,并且影响了用户体验和网络效率。因此,后续的 HTTP/2 和 HTTP/3 协议都致力于解决这些效率问题,提高了网络的性能和效率。
5. http/2.0 多路复用
HTTP/2.0 引入了多路复用(Multiplexing)机制,是解决 HTTP/1.x 中队头阻塞(Head-of-line Blocking)问题的关键特性之一。多路复用允许在单个 TCP 连接上同时发送和接收多个 HTTP 请求和响应,从而避免了每个请求都需要等待前一个请求的响应导致的延迟问题。
具体来说,多路复用的工作原理如下:
- 单个连接: 在 HTTP/2.0 中,客户端和服务器之间仍然使用单个 TCP 连接进行通信,但这个连接上可以同时处理多个请求和响应。
- 帧和流: http2.0 引入了二进制数据帧和流的概念。其中帧对数据进行顺序标识。这样当接收到数据时,就可以按照序列对数据进行合并。同样,有了序列,服务器就可以并行传输数据,这就是流做的事情。
- 数据流多路复用: 在单个 TCP 连接上,可以同时发送和接收多个数据流(Stream),每个数据流都有唯一的标识符。这意味着不同的请求和响应可以独立地、并发地在同一个连接上传输,彼此之间不会相互阻塞。
- 无序交错的帧: 在多路复用中,各个数据流的帧可以交错发送和接收,即使一个数据流的某个帧被阻塞了,也不会影响其他数据流的帧的传输。
多路复用的引入显著提高了 HTTP/2.0 的性能和效率,尤其在高并发、大流量、高延迟网络等场景下,可以更好地利用网络资源,减少了连接的建立和关闭开销,提高了网络的整体吞吐量和响应速度。
6. 不适用 HTTP/2.0 的优化
- JS 文件合并
- 雪碧图
- 多域名提高浏览器下载速度