简介
http1.0: 1.0版本中每个TCP连接只能发送一个请求,数据发送完毕连接就关闭,如果还要请求其他资源,就必须重新建立TCP连接。(TCP为了保证正确性和可靠性需要客户端和服务器三次握手和四次挥手,因此建立连接成本很高)
http1.1:
- 长连接:新增Connection字段,默认为keep-alive,保持连接不断开,即 TCP 连接默认不关闭,可以被多个请求复用;
- 管道化:在同一个TCP连接中,客户端可以发送多个请求,但响应的顺序还是按照请求的顺序返回,在服务端只有处理完一个回应,才会进行下一个回应;
- host字段:Host字段用来指定服务器的域名,这样就可以将多种请求发往同一台服务器上的不同网站,提高了机器的复用,这个也是重要的优化;
http2.0:
- 二进制格式:1.x是文本协议,然而2.0是以二进制帧为基本单位,可以说是一个二进制协议,将所有传输的信息分割为消息和帧,并采用二进制格式的编码,一帧中包含数据和标识符,使得网络传输变得高效而灵活;
- 多路复用:2.0版本的多路复用多个请求共用一个连接,多个请求可以同时在一个TCP连接上并发,主要借助于二进制帧中的标识进行区分实现链路的复用;
- 头部压缩:2.0版本使用使用HPACK算法对头部header数据进行压缩,从而减少请求的大小提高效率,这个非常好理解,之前每次发送都要带相同的header,显得很冗余,2.0版本对头部信息进行增量更新有效减少了头部数据的传输;
- 服务端推送:在2.0版本允许服务器主动向客户端发送资源,这样在客户端可以起到加速的作用;
性能比较
pingdom 测试结果:
什么场景下http2.0性能提升明显?
提升原因
影响网络性能的关键因素:“带宽” 和 “延时”
二进制分帧层:— http2.0的基石
在二进制分帧层上,http2.0会将所有传输信息分割为更小的消息和帧,并对它们采用二进制格式的编码将其封装,新增的二进制分帧层同时也能够保证http1.X的各种动词,方法,首部都不受影响,兼容上一代http标准。其中,http1.X中的首部信息header封装到Headers帧中,而request body将被封装到Data帧中。
HTTP/2中最小的通信单元,每个单元都包含一个帧头,该帧头至少标识帧所属的流。
- 所有通信都通过单个TCP连接进行,该连接可以承载任意数量的双向流。
- 每个流都有一个唯一的标识符和可选的优先级信息,用于传输双向消息。
- 每条消息都是逻辑HTTP消息,如请求或响应,由一个或多个帧组成。
- 帧是承载特定类型数据的最小通信单元——例如HTTP标头、消息有效负载等。来自不同流的帧可以交错,然后通过每个帧标题中的嵌入式流标识符重新组装。
多路复用:—连接共享
使用HTTP/1.x,如果客户端想提出多个并行请求来提高性能,则必须使用多个TCP连接。这是HTTP/1.x框架的直接后果,该模型确保每个连接一次只能交付一个响应(响应排队)。更糟糕的是,这也会导致线头阻塞和底层TCP连接的使用效率低下。
HTTP/2中新的二进制帧层允许客户端和服务器将HTTP消息分解为独立帧,将它们交织在一起,然后在另一端重新组装它们,从而实现完整的请求和响应复用,这是HTTP/2最重要的增强功能。
TTFB:表示客户端从发出请求后到收到服务器响应的第一个字节的时间,即包含了一个c/s的网络来回时间和服务器处理请求的时间
可以看到http1.1在一个TCP连接中只有等一个请求处理完成之后才能处理下一个请求,而http2.0依赖于二进制分帧层和多路复用技术可以同时并行处理请求,减少了http1.1中的阻塞问题,这也是http2.0对网络时延优化好的重要原因;
http1.1协议中请求一个服务端一般允许开放6个tcp连接,而http2.0只有1个tcp连接,虽然节省了资源,但是在比较特殊的场景:小时延(忽略不计),小带宽的场景中,http1.1相当于6个管道下载资源,http2.0则是一个管道,此时http2.0的加载速度反而不如http1.1;
当然这种场景如今已经不多见了,随着互联网的高速发展,带宽已经不是影响响应的主要因素,大部分的情况下,延迟是影响响应速度的主要因素。
流优先级
把http消息分为很多独立帧之后,就可以通过优化这些帧的交错和传输顺序进一步优化性能,HTTP/2标准允许每个流具有相关的权重和依赖性:分配处理资源和客户端与服务器间的带宽,不同优先级的混合也是必须的。客户端会指定哪个流是最重要的,有一些依赖参数,这样一个流可以依赖另外一个流。优先级别可以在运行时动态改变,当用户滚动页面时,可以告诉浏览器哪个图像是最重要的,你也可以在一组流中进行优先筛选,能够突然抓住重点流(偏向但并不是绝对的优先)。
- 优先级最高:主要的html
- 优先级高:CSS文件
- 优先级中:js文件
- 优先级低:图片
每个服务器源一个链接
受益于的二进制框架,HTTP/2不再需要使用多个TCP并行连接;每个流被拆分为多个帧,可以并行、交错和优先排序。所有HTTP/2连接都是持久的,每个源只需要一个连接,通过重用相同的连接,HTTP/2既能更有效地利用每个TCP连接(TCP慢启动),又能显著减少整体协议开销,有助于提高吞吐量和降低运营成本。
头部压缩
每个HTTP传输都包含一组标头,描述传输的资源及其属性。在HTTP/1.x中,此元数据始终以纯文本形式发送,每次传输添加500-800字节的开销,如果使用HTTP Cookie,有时会增加千字节;HTTP/2使用HPACK压缩算法压缩请求和响应头元数据,HTTP/2的HPACK算法使用一份索引表来定义常用的http Header,把常用的 http Header 存放在表里,请求的时候便只需要发送在表里的索引位置即可。
服务端推送
HTTP/2的另一个强大的新功能是服务器能够为单个客户端请求发送多个响应。也就是说,除了响应原始请求外,服务器还可以向客户端推送其他资源,而无需客户端请求每个资源!
升级难度
综上所述:后端服务,服务服务之间没有必要使用HTTP2.0协议,整体来看,整体环境支持体系并不完善,且在小时延场景下,性能并不会有大幅提升,更重要的是HTTP2.0是基于HTTPS的协议,在后端服务之间使用并不合适,如果优化不当,甚至适得其反;
应用HTTP2.0
如果你使用 SSL/TLS(简称 TLS),那么 HTTP/2 可以提升网站性能。如果你没有,那在使用 HTTP/2 之前要先支持 TLS。这时候,使用 TLS 的性能损耗大致可以被使用 HTTP/2 的性能提升抵销。不过还是建议你在实际应用之前先测试一下。
事实上,部署 HTTP/2 并不难。如果使用 NGINX,只要在配置文件中启动相应的协议就可以了。浏览器和服务器会协商采用什么协议,如果浏览器支持 HTTP/2(而且也在使用 TLS),就会使用 HTTP/2。
HTTP/2 要求 Nginx 1.9.5+,,OpenSSL 1.0.2+
nginx配置http2.0:
server {
listen 442 ssl http2;
#证书
ssl_certificate /usr/local/etc/nginx/ssl-cert.pem;
ssl_certificate_key /usr/local/etc/nginx/ssl-key.pem;
add_header Cache-Control no-store; #浏览器加载不使用缓存
location / {
root /usr/local/share/nginx/html;
index index2.0.html;
}
}
HTTP的应用程序语义相同,没有对提供的功能或核心概念进行更改,如HTTP方法、状态代码、URI和标头字段
性能瓶颈:启用http2.0后会给性能带来提升,但同时也会带来新的性能瓶颈。因为现在所有的压力集中在底层一个TCP连接之上,TCP很可能就是下一个性能瓶颈,比如TCP分组的队首阻塞问题,单个TCP packet丢失导致整个连接阻塞,无法逃避,此时所有消息都会受到影响。未来,服务器端针对http 2.0下的TCP配置优化至关重要。
前端改动:前端针对http1.1的优化可能不在需要
后端改动:后端不需要改动