网络复习-0

2021-05-19 04:51:302024-04-10 18:39:18

keep-alive

http协议是建立在tcp协议上的应用层协议,http协议的早期版本(HTTP/0.9和早期HTTP/1.0)最初是一个非常简单的协议,通信方式也是采用简单的请求-应答模式,即:客户端与服务器的每次请求都需要建立连接,服务器响应后即断开,再请求再重新创建

http多次创建tcp

tcp连接的新建成本较高,因为客户端和服务器建立连接时需要三次握手,传输一次数据耗时2xRTT + 数据传输时间:

http传输一次数据耗时

释放时则是四次挥手,需要2xRTT

所以HTTP/1.0引入了keep-alive,HTTP/1.0中默认是关闭的,可在请求头中添加Connection: keep-alive开启;HTTP/1.1默认开启

所谓keep-alive就是服务器在发送响应后在一定时间(通过http请求头Keep-Alive: timeout max设置)内仍然保持这条连接,使得同一个客户端可以继续使用这条连接传输后续的http请求报文和响应报文

需要将 Connection 首部的值设置为 "keep-alive" 这个首部才有意义。同时需要注意的是,在HTTP/2 协议中, Connection 和 Keep-Alive 是被忽略的;在其中采用其他机制来进行连接管理。

http多次创建tcp

http2多路复用

为什么HTTP/2引入多路复用:

HTTP/1.0引入的Keep-Alive有两种工作方式: 非流水线without pipelining流水线with pipelining

  • 非流水线 客户在收到上一个请求的响应后才能发送下一个请求。因此在TCP连接已建立后客户每访问一次对象就要用一个RTT,相较于非持续连接节省了一个RTT。但这仍然有一定的缺点:服务器在发送完一个对象后其TCP连接就处于空闲状态,浪费资源

  • 流水线 客户在收到HTTP响应报文之前可以继续发送新的报文。于是一个接一个的请求报文到达服务器后,服务器就可以连续发回响应报文,但这要求服务器必须按照请求发送的顺序返回响应,当顺序请求多个文件时,其中一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,这就是队头阻塞 (Head-Of-Line Blocking)

HTTP2的多路复用

首先引入帧(frame)和流(stream),因为HTTP/1.x是基于文本的,就导致在传输时只能串行去传。HTTP/2是基于流的,它就可以把HTTP消息分解为独立的帧,交错发送,然后在另一端通过帧中的标示重新组装,这就是多路复用。多路复用实现了在同一个TCP连接中,同一时刻可以发送多个请求和响应,且不用按照顺序一一对应,即使某个请求任务耗时严重,也不影响其他连接的正常执行

steam是一个独立的、客户端和服务端在HTTP/2连接下交换帧的双向序列集

HTTP/2在端点之间建立连接后,以Frame为基本单位交换数据。stream为一组共享同一streamID的frame集合

Connection,Stream,Frame 构成了这样的关系:Connection 和 Stream 是一对多的关系,Stream 和Frame也是一对多的关系

这样,就可以允许来自多个 Stream 的多个Frame 交错发送,在一个Connection上执行多播通信 (multiplexed communication)

并且,客户端也可以在一个TCP Connection 上发送多个请求。在同一个Connection上的请求现在可以不按次序给出响应——服务端可以根据QoS(服务质量)规则来决定响应内容的次序

http2的多路复用

http常见首部字段

名称 意义 备注
Cache-Control 缓存设置Cache-Control: private, max-age=0, no-cache no-cache: no-cache 无 强制向源服务器再次验证
no-store: 不缓存
max-age: 100: 100s后失效
Connection 控制不再转发给代理的首部字段;管理持久连接 Connection: Upgrade/Keep-Alive
Date 创建HTTP报文的日期和时间 Date: Tue, 03 Jul 2012 04:40:59 GMT
Accept 告知服务器客户端可以处理的媒体类型及媒体类型的想对优先级 Accept: text/html,application/xhtml+xml,application/xml
Content-Length 本次返回的数据长度
Host 服务器域名/ip

cache-control

请求头部

Cache-Control: max-age=<seconds>
Cache-Control: max-stale[=<seconds>]
Cache-Control: min-fresh=<seconds>
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: no-transform
Cache-Control: only-if-cached

响应头部

Cache-Control: must-revalidate
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: no-transform
Cache-Control: private
Cache-Control: public
Cache-Control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-Control: s-maxage=<seconds>

public: 表示可以被任何对象(浏览器、服务器、代理服务器等)缓存

private: 表示只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存)

no-cache: 使用协商缓存

no-store: 不使用任何缓存

max-age=<seconds>: 设置缓存存储的最大周期,超过这个时间(相对于请求的时间)缓存被认为过期

s-maxage=<seconds>: 针对于缓存服务器

max-stale[=<seconds>]: 表明客户端愿意接收一个已经过期的资源。可以设置一个可选的秒数,表示缓存最大的超时时间,该时间内可正常接收

min-fresh=<seconds>: 要求缓存服务器返回至少还未过指定时间的缓存资源。比如当指定min-fresh为60,过了 60 秒的资源都无法作为响应返回了

http的演进

http的演进

http1.1使用添加了keep-clive来复用tcp连接,改善了http1.0频繁创建tcp连接的性能开销。此外支持流水线(with pipelining)传输,使得客户端可以专注于发送而不必等待上一个请求的响应。可以在一定程度上减少整体的响应时间。但流水线也存在问题,虽然客户端可以一直发送,但服务器需要顺序响应,如果某一响应较耗时,那个客户端也一直收不到其他的响应(队头阻塞问题)。此外http1.1还有请求、响应头部(Header)较大(未经压缩就发送)、没有请求优先级控制等问题。

http2.0是基于https的,首先安全性有了保障,此外性能上较http1.1也有了不少改进。

  1. http2.0会进行头部压缩:如果你发出多个请求,它们的头部是一样或相似的,那么协议会帮你消除重复的部分。

  2. http2不再像http1.x里的纯文本形式的报文,http/2是基于二进制的,头部和数据体统称为帧(frame),这样虽然对人不太友好,但对于计算机来讲不用再将数据从文本转为二进制,而是直接解析二进制报文,增加了数据传输线率

  3. http/2的数据包不是顺序发送的,而是基于流的,同一个连接里可能有不同的请求/响应。因此每一个数据流都标记这独一无二的编号,客户端还可以指定数据流的优先级。

  4. http/2采用了多路复用的策略来进一步提升性能,移除了http/1.x中的流水线式的串行请求/响应方式。http/2可以在同一个连接中并发处理多个请求或响应,而不用排队等待,再也不会出现对头阻塞的问题了

  5. 服务器推送。

http/3把tcp改成了udp

参考

了解 HTTP/1.x 的 keep-alive 吗?它与 HTTP/2 多路复用的区别是什么?

MDN-HTTP

Why HTTP/2 does multiplexing altough tcp does same thing?