这篇文章主要讲解了“怎么启用HTTP/2”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么启用HTTP/2”吧!
HTTP历史
HTTP/0.9是个相当简单的协议,它只有一个GET方法,没有首部。HTTP/1 新增了大量内容:首部,晌应码,重定向,错误,条件请求,内容编码,更多的请求方法。HTTP/1.1强制增加host首部,增加缓存相关首部,传输编码,默认持久连接等。HTTP2基于google的SPDY,基本就是SPDY规范化,2015年HTIP/2 成为正式协议。0.9-2的协议都是基于tcp协议。为什么http3会有基于udp实现的讨论?即使基于udp也仍然要在应用程序重复实现tcp已经实现的可靠连接,拥塞控制等特性。基于udp实现的考虑是传输层协议内置在操作系统里实现,应用层开发人员没有对它的控制权,如果能将tcp这些特性移到应用层,就可以快速发展迭代。
HTTP/1.1问题
1.队头阻塞
HTTP协议是建立在TCP协议之上请求应答模式的半双工通信协议,而浏览器很少只从一个域名获取一份资源,大多数时候,它希望能同时获取许多资源。假设客户端与服务器开启一条TCP连接通信,客户端需要获取10个资源,只能是一个个的获取。客户端首先请求第1个资源,接收到服务端响应后再继续请求第2个,依此类推,如果获取第一个资源比较慢就会阻塞后面的请求。客户端要想发起多个并行请求以提升性能,则必须使用多个 TCP 连接,但是每个连接仍会受到“队头阻塞”的影响。现代浏览器会针对单个域名开启6个TCP连接。一个客户端对任何服务器或代理最多只能维护2条持久连接,以防服务器过载。
2.低效的TCP利用
如果没有开启keepalive则每个请求都会重复TCP连接建立的过程,即三次握手和四次握手。开启keepalive后主要是TCP拥塞控制的影响。
3.臃肿的首部
1.1版本无法压缩首部,首部通常有很多,并且如果带有cookie则会更大。
4.无法指定优先级
5.第三方资源
Web页面上请求的很多资源完全独立于站点服务器的控制,我们称这些为第三方资源。很多第三方资源都不在 Web 开发者的控制范围内,所以很可能其中有些资源的性能很差,会延迟甚至阻塞页面谊染。
HTTP/2特性
二进制协议
HTTP/1.1是文本协议,而HTTP/2是二进制协议。经过网络传输必然是都二进制,这里所谓文本协议,二进制协议的意思应当是报文的内容。HTTP/1.1中request line和header都是ASCII编码,而body内容类型依据content-type判断,并且判定body是否结束是根据content-length或者分块传输,要解析整个HTTP报文内容,都是根据文本字符CRLF来解析。所以HTTP/1.1的报文是经过文本编码的二进制再交付给TCP传输。HTTP/2中保留了HTTP/1.1 的语义(包括各种动词、方法、首部),不同的是传输期间对它们的编码方式变了。HTTP/2 将所有传输的信息分割为更小的消息和帧,并采用二进制格式对它们编码。
+-----------------------------------------------+ | Length (24) | +---------------+---------------+---------------+ | Type (8) | Flags (8) | +-+-------------+---------------+-------------------------------+ |R| Stream Identifier (31) | +=+=============================================================+ | Frame Payload (0...) ... +---------------------------------------------------------------+
其中length占用24bit,表示payload数据的长度,24bit能表示的数值为0到$2^{24}$-1,而1mb=$2^{20}$,所以理论上payload最大是$2^4$mb,$2^{14}$是默认的最大帧大小。这样服务器只需要读取到length与type,也就是前9个字节,就只可以知道数据的长度,以及数据帧的类型。
可以理解为http协议的各种请求方法,首部语义都保留了,区别在于,HTTP/1.1是把这些明文内容使用CRLF分隔直接传输,而HTTP/2则对明文内容封装到帧的payload里面。
请求与响应复用
HTTP/2 的主要目标是通过支持完整的请求与响应复用来减少延迟,HTTP/2只会建立并复用一条TCP连接。客户端和服务器可以将 HTTP 消息分解为互不依赖的帧,然后交错发送,最后再在另一端把它们重新组装起来(根据Stream Identifier区分)。客户端可以并行交错地发送多个请求,请求之间互不影响。服务器端可以并行交错地发送多个响应,响应之间互不干扰。
连接管理
大多数 HTTP 传输都是短暂的,而 TCP 则针对长时间的批量数据传输进行了优化。 通过重用相同的连接,HTTP/2 既可以更有效地利用每个 TCP 连接,也可以显著降低整体协议开销。
HTTP/1.1的持久连接是有超时时间的,HTTP/2没有超时时间的概念,它可以被认为是永久连接的,但是不可能是一直连着的,即使HTTP没有明确规定超时,TCP也有超时的。所以如何理解这个永久呢?
HTTP/2 connections are persistent. For best performance, it is expected that clients will not close connections until it is determined that no further communication with a server is necessary (for example, when a user navigates away from a particular web page) or until the server closes the connection.
Servers are encouraged to maintain open connections for as long as possible but are permitted to terminate idle connections if necessary.
HTTP/2连接是持久的,为了最好的性能,客户端不应当关闭连接,直到它认为不需要与服务器进行进一步的通信(例如,当用户从一个特定的网页导航离开时)或者直到服务器关闭连接。服务端也应当尽可能长的保持连接,但是也允许服务器主动关闭连接释放资源。
数据流优先级
HTTP/2 标准允许每个数据流都有一个关联的权重和依赖关系。
首部压缩
HTTP/2 使用 HPACK 压缩格式压缩请求和响应标头元数据。
流控制
流控制是一种阻止发送方向接收方发送大量数据的机制,以免超出后者的需求或处理能力: 发送方可能非常繁忙、处于较高的负载之下,也可能仅仅希望为特定数据流分配固定量的资源。 例如,客户端可能请求了一个具有较高优先级的大型视频流,但是用户已经暂停视频,客户端现在希望暂停或限制从服务器的传输,以免提取和缓冲不必要的数据。 再比如,一个代理服务器可能具有较快的下游连接和较慢的上游连接,并且也希望调节下游连接传输数据的速度以匹配上游连接的速度来控制其资源利用率;等等。
服务器推送
服务器可以对一个客户端请求发送多个响应,除了对最初请求的响应外,服务器还可以向客户端推送额外资源。这里的推送并不意味着可以全双工通信了,可以替换websocket,前提是客户端主动发起一次请求才可以。另外,在使用 nginx 作为反向代理时根本不支持这种推送。
启用HTTP/2
HTTP/2 over https,因此要启用HTTP/2,必须现在服务器配好证书。要启用HTTP/2无非就是需要客户端与服务器都支持HTTP/2通信协议,几乎每个现代的浏览器和版本高一点的web服务器都支持 HTTP/2。只需要服务器开启HTTP/2,客户端会优先使用HTTP/2连接,如果服务器不支持HTTP/2,则会退回到HTTP/1.1 。
现代服务端部署方式通常不只有一个web服务器,从浏览器发出的请求到最终接口获取数据,中间可能存在诸多代理,比如云服务的slb,gateway,k8s ingress,后端服务tomcat等,问题在于是否需要全链路启用HTTP/2?如果后端服务器tomcat启用HTTP/2,但是中间nginx没有启用,本质上还是相当于没有启用。这个问题可以类比https,通常我们只会在整个链路的最边缘节点配置一次https,由于最边缘节点到后端服务几乎是内网访问,不存在中间人攻击问题,所以从最边缘节点到后端服务完全没有必要再次加密解密。
HTTP/2 的主要优点是可以提升高延迟、低带宽连接的速度,连接到边缘服务器(在这种情况下为反向代理)的用户通常处在这样的网络环境下。从反向代理到其他 Web 基础架构的流量一般处于低延迟、高带宽、短距离的网络环境中(即使不是同一台机器,也通常是相同的数据中心),因此此场景下通常不需要考虑 HTTP/1.1 的性能问题。
反向代理到服务器的连接数不受限于浏览器设置的 6 个连接。Nginx 已经声明,它不会为代理连接实现HTTP/2。
综上,如果要启用HTTP/2,只在最边缘节点启用就可以了。