大家好,今天要跟大家谈论的是为什么需要HTTP/2,我们在谈论这个话题的时候,实际上在谈论的是HTTP的现在、过去和将来。在本文中,将重点介绍HTTP/1的过去,现在和其面临的固有问题。
http/2 连接
HTTP作为非常通用的广泛使用的协议,其经历了比较长的一个发展的过程。
1991年左右,发布了第一版的HTTP 0.9版本。一开始并没有很多的header字段和复杂的功能,客户端仅仅发送GET方法获取文件,客户端发送文件并关闭连接,就这么简单。
HTTP 0.9版本
随着互联网的发展以及浏览器的诞生,我们需要扩展HTTP协议,使用更加通用和适应更多复杂的场景。1995年HTTP1.0版本应运而生了。
HTTP 1.0版本
HTTP1.0版本相比之前进行了大量协议上的修改,这些改变包括:
请求可能由多个换行符分隔的头字段组成。
响应体以响应状态码为前缀。
响应体有自己的一组换行符分隔的头字段。
响应体不限于超文本。
服务器和客户端之间的连接在每次请求后关闭。
HTTP1.0之后,随着互联网的进一步发展,网络环境发生了不少变化,这些变化包括,当我们访问一个网页时,这个网页的图片等资源可能来自于外部几十个网站,即更多的资源分布在不同的主机中。
请求瀑布图,更多的资源分布在不同的主机中
如果这些资源我们都一个一个的去访问的话,会经历DNS查找,然后TCP三次握手,TLS加密,然后再加上HTTP请求与回复,那这个时候资源加载太慢,严重影响了访问速度。
第二个特点是,资源的大小越来越大。
第三个特点是,相对于网络带宽,网络往返延迟瓶颈更大
为了应对上面的问题,1997年时HTTP1.1提供了一些解决的办法,当然它也解决了早期协议的一些问题。HTTP1.1引入一些比较关键的性能优化和提高,包括:
keepalive机制,可以重复使用连接,从而节省时间。
请求pipeline机制
chunk机制
缓存控制机制
内容协商,包括语言、编码和类型
range request(发送一部分请求给客户端)
下面讲解3个比较重要的优化。包括比较熟知的keepalive机制.
没有keepalive机制,两个请求都需要建立tcp连接
keepalive保证在默认的情况下,客户端跟服务器保持长链接状态,而不是每一次请求完了就关闭掉,通过复用这个链接,减少握手的成本。
keepalive机制减少握手的成本
HTTP1.1还包括了分块编码传输的流式处理机制,即一开始处理的过程中,可能并不明确要传输数据的大小,直到最后传输完成。
HTTP1.1还包括了请求流水线(request pipeline)机制。
未使用pipeline机制,往返的延迟增大了资源获取时间
在过去,客户端发送一条消息给服务器,等待服务器处理完毕返回之后,客户端继续发送第二条请求。那可能的优化是客户端可不可以一次就发送两三条请求给服务器,这样大大避免了往返的延迟。
虽然这些优化看起来比较好,但是HTTP1.1 并没有彻底解决之前提到的瓶颈。
HTTP1.1 pipeline机制对提高性能的解决方案并不彻底,举一个栗子,客户端发送了两个请求,分别是获取HTML文件以及获取CSS文件,但是,假如说HTML这个文件服务器处理了很长时间,那这个时候CSS这个文件也发送不过来,因为它被前面的HTML请求给堵塞住了,这就是head of line问题,即在http层的阻塞问题。
pipeline机制,前一个请求堵塞后一个请求
稍微理想一些的情况是服务器并行两个请求,处理完了以后分别发给客户端,这个时候仍然有堵塞问题,但速度要稍微快一些。
稍微理想一些的改进办法
更理想的情况可能是一种多路复用的机制。比如CSS处理20毫秒,那服务器处理完成之后,立马就发给客户端,然后,再过20毫秒,HTML也处理好了,那么也立即发送,这个时候就解决了堵塞问题。
但是很遗憾,HTTP1.1 协议的限制没有解决这样的问题。HTTP1.1面临的其他问题是,现在请求的header字段和cooking越来越大,每一次请求都携带了一些没有用的数据,资源大大浪费
header越来越大
cookie数据量巨大
在实践中,http1.1解决head of line问题是通过与服务器创建多个TCP连接来实现的,这种方式在TCP层仍然问题,笔者将在介绍http/3时,介绍TCP层面临的固有问题。
在10多年的探索中,2012年左右提出了HTTP/2的概念,它源自早期的实验性SPDY协议,最初由Google开发。然后在2015年,IETF正式发布HTTP/2标准的版本。HTTP/2 仍然建立在TCP之上,主要通过
二进制协议
多路复用
请求优先级
头部压缩
等机制对性能进行优化。目前,HTTP/2已经被主流的浏览器和代理服务器支持。截至 2021 年 10 月,排名前 1000 万个网站中有 47%支持 HTTP/2(wiki)
在下一篇文章中,将分析HTTP/2实现的关键细节。
总结
本文简要介绍了http的历史,主要通过http/1 面临的问题,header和cookie太大,面临head of line堵塞问题,请求pipeline机制面临的问题,表明了我们需要一种新的协议克服http/1面临的问题,升级到http/2将得到进一步的性能优化。
参考资料:
《HTTP/2 in Action》
《High Performance Browser Networking》
《HTTP: The Definitive Guide》