大家好,我是蜗牛,今天我们聊聊HTTP协议,通过这篇文章我们能了解到不同版本HTTP优缺点、他们之间的性能差异以及现在主流的HTTP协议用的那个版本
HTTP/1.1 时代HTTP/1.1 对 HTTP/1.0 做了许多优化,也是当今使用得最多的 HTTP 协议:
- 持久化连接以支持连接重用
- 分块传输编码以支持流式响应
- 请求管道以支持并行请求处理
- 字节服务以支持基于范围的资源请求
- 改进的更好的缓存机制
在 HTTP/1.0 时代,每一个请求都会重新建立一个 TCP 连接,一旦响应返回,就关闭连接。而建立一个连接,则需要进行三次握手(https的话则是9次握手),这极大的浪费了性能
因此 HTTP/1.1 新增了「keep-alive」功能,当浏览器建立一个 TCP 连接时,多个请求都会使用这条连接。(现如今大多数浏览器默认都是开启的)
PipeLining 管道持久连接解决了连接复用问题,但还是存在着一个问题:在一个 TCP 连接中,同一时间只能够发送一个请求,并且需要等响应完成才能够发送第二个请求。
因此 HTTP/1.1 制订了 PipeLining 管道,通过这个管道,浏览器的多个请求可以同时发到服务器,但是服务器的响应只能够一个接着一个的返回 ( 但各大浏览器有些不支持/默认关闭,因此这功能可以说是鸡肋)
因为每一条连接同时只能够返回一个响应,因此浏览器为了改善这种情况,会同时开启4~8个 TCP 连接进行发送请求。
小结在 HTTP/1.1 时代主要增加了:
- keep-alive 选项,建立连接后,在一定时间内不会断开,其他请求都可以使用这条连接。
- pipelining 管道,通过这个管道,浏览器的多个请求可以同时发到服务器,但是服务器的响应只能够一个接着一个的返回 ( 但各大浏览器有些不支持/默认关闭,因此这功能可以说是鸡肋)
连接或拼接JS和CSS文件,雪碧图,以减少HTTP请求,同时浏览器可缓存这些静态资源,为下次访问节约时间。但是这样带来的副作用是,维护成本高,其中某一个小改动都会使得整个拼接后的文件发生改变,重新缓存。
当然并不是说无止境的拼接,建议大小为:30~50 KB
2、域名分区由于浏览器的限制,同一个域名下最多只能建立6个连接(不同的浏览器限制不一样)。我们通常使用子域名来减少所有资源在只有一个连接时的产生的排队延迟。这个显然不适用在HTTP2中,因为不同的域需要建立不同的连接。
3、资源内嵌对于不常用的,较小大资源内嵌在文档中,比如base64的图片,以减少HTTP请求,但是这样的资源不能在浏览器中缓存,也不可能被其他页面共享,同时还有可能编码之后的资源变等更大了。在HTTP2中,这样的资源就可以使用SERVER PUSH来推送。
建议:
- 只考虑嵌入1~2 KB 以下的资源,因为小于这个标准的资源经常会导致比它自身更高的HTTP 开销
- 如果文件很小,而且只有个别页面使用,可以考虑嵌入。理想情况下,最好是只用一次的资源
- 如果文件很小,但需要在多个页面中重用,应该考虑集中打包
- 如果小文件经常需要更新,就不要嵌入了
- 通过减少 HTTP cookie的大小将协议开销最小化
由于现代网页的不断丰富, HTTP/1.1 协议的性能也逐渐吃不消,因此2012年google(google就是牛逼)如一声惊雷提出了SPDY的方案,实际上,HTTP/2.0 也是以 SPDY 作为原型进行开发的。
SPDY基础功能多路复用(multiplexing)多路复用通过多个请求stream共享一个tcp连接的方式,解决了http1.x holb(head of line blocking)的问题,降低了延迟同时提高了带宽的利用率。
请求优先级(request prioritization)多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的HTML内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。
header压缩前面提到过几次http1.x的header很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量。SPDY对header的压缩率可以达到80%以上,低带宽环境下效果很大。
SPDY 现已经被大多数浏览器以及 WEB 服务器所支持,但为了推进 HTTP/2.0, Google 已经宣布在 2016年对其停止开发。
HTTP/2.0 时代2015年5月, HTTP/2.0 在万众瞩目下以RFC 7540正式发表。(热烈鼓掌~啪啪啪啪~~)
二进制分帧在应用层与传输层之间增加一个二进制分帧层,以此达到“在不改动HTTP的语义,HTTP 方法、状态码、URI及首部字段的情况下,突破HTTP1.1的性能限制,改进传输性能,实现低延迟和高吞吐量。”
在二进制分帧层上,HTTP2.0会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中HTTP1.x的首部信息会被封装到Headers帧,而我们的request body则封装到Data帧里面。
压缩头部HTTP/2.0规定了在客户端和服务器端会使用并且维护「首部表」来跟踪和存储之前发送的键值对,对于相同的头部,不必再通过请求发送,只需发送一次
事实上,如果请求中不包含首部(例如对同一资源的轮询请求),那么首部开销就是零字节。此时所有首部都自动使用之前请求发送的首部。
如果首部发生变化了,那么只需要发送变化了数据在Headers帧里面,新增或修改的首部帧会被追加到“首部表”。首部表在 HTTP2.0的连接存续期内始终存在,由客户端和服务器共同渐进地更新。
多路复用HTTP/2.0 时代拥有了「多路复用」功能,意思是: 在一条连接上,我可以同时发起无数个请求,并且响应可以同时返回。
这个连接可以承载任意数量的双向数据流。在过去, HTTP 性能优化的关键并不在于高带宽,而是低延迟。TCP 连接会随着时间进行自我调节,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调节则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。HTTP/2.0 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。
这种单连接多资源的方式,减少服务端的连接压力,内存占用更少,连接吞吐量更大;而且由于 TCP 连接的减少而使网络拥塞状况得以改善,同时慢启动时间的减少,使拥塞和丢包恢复速度更快。
客户端和服务器可以把HTTP消息分解为互不依赖的帧,然后乱序发送,最后再在另一端把它们重新组合起来。注意,同一链接上有多个不同方向的数据流在传输。客户端可以一边乱序发送stream,也可以一边接收者服务器的响应,而服务器那端同理。
也就是说,HTTP2.0通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流。
注意,对一个域名,只需要开启一条 TCP 连接,请求都在这条 TCP 连接上干活。
因此在 HTTP/2.0 时代,之前的合并 JS、CSS 文件技巧,反而不适用了。
请求优先级既然所有资源都是并行发送,那么就需要「优先级」的概念了,这样就可以对重要的文件进行先传输,加速页面的渲染。
服务器推送在 HTTP2.0中,服务器推送是指在客户端请求之前发送数据的机制。如果一个请求是由你的主页发起的,服务器很可能响应主页内容、logo以及样式表,因为它知道客户端会用到这些东西。这相当于在一个 HTML 文档内集合了所有的资源,不过与之相比,服务器推送有一个很大的优势:可以缓存!
强制 SSL虽然 HTTP/2.0 协议并没声明一定要用 SSL,但是 Google Chrome 等浏览器强制要求使用 HTTP/2.0 必须要用上 SSL, 也就是说必须要:https://
http:// 将继续使用 http/1.0
对优化的影响:- 因为“所有的HTTP2.0的请求都在一个TCP链接上”,“资源合并减少请求”,比如CSS Sprites,多个JS文件、CSS文件合并等手段没有效果,或者说没有必要。
- 因为“多路复用”,采用“cdn1.cn,cdn2.cn,cdn3.cn,打开多个TCP会话,突破浏览器对同一域名的链接数的限制”的手段是没有必要的。因为因为资源都是并行交错发送,且没有限制,不需要额外的多域名并行下载。
- 因为“服务器推送”,内嵌资源的优化手段也变得没有意义了。而且使用服务器推送的资源的方式更加高效,因为客户端还可以缓存起来,甚至可以由不同的页面共享(依旧遵循同源策略)
1. 需要浏览器的支持,目前最新版的 Chrome、Opera、 FireFox、 IE11、 edge 都已经支持了
2. 需要 WEB 服务器的支持,比如 Nginx , H20
如果浏览器或服务器有一方不支持,那么会自动变成 Http/1.1
HTTP/1.1 HTTP/2.0性能比较https://http2.akamai.com/demo 这是Akamai公司建立的一个官方演示,这个演示同时请求379张图片,用于展示HTTP/1.1和HTTP/2的性能差距。不同的电脑配置、网络情况以及服务器负载等情况不同,得到的结果肯定也不同,下图是使用自己的电脑加载时间截图:
参考:
https://linjunzhu.github.io/blog/2016/03/10/http2-zongjie/
https://www.jianshu.com/p/52d86558ca57
,