浏览器每次请求都需要与服务器建立一个TCP连接,服务器处理完成以后立即断开TCP连接(无连接),服务器不跟踪也每个客户单,也不记录过去的请求(无状态)。
这种无状态性可以借助cookie/session机制来做身份认证和状态记录。
HTTP1.1继承了HTTP1.0的简单,克服了HTTP1.0性能上的问题。
深入理解可参考这篇文章: https://mp.weixin.qq.com/s/a83_NE-ww36FZsy320MQFQ
所有HTTP2.0通信都在一个TCP链接上完成,这个链接可以承载任意流量的双向数据流。
每个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(Stream_id)重新封装。
多路复用(连接共享)可能会导致关键字被阻塞,HTTP2.0里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回客户端,数据流还可以依赖其他的子数据流。
可见,HTTP2.0实现了真正的并行传输,它能够在一个TCP上进行任意数量的HTTP请求。而这个强大的功能基于“二进制分帧”的特性。
基于Google的QUIC,HTTP3 背后的主要思想是放弃 TCP,转而使用基于 UDP 的 QUIC 协议。
与 HTTP2 在技术上允许未加密的通信不同,QUIC 严格要求加密后才能建立连接。此外,加密不仅适用于 HTTP 负载,还适用于流经连接的所有数据,从而避免了一大堆安全问题。建立持久连接、协商加密协议,甚至发送第一批数据都被合并到 QUIC 中的单个请求/响应周期中,从而大大减少了连接等待时间。如果客户端具有本地缓存的密码参数,则可以通过简化的握手(0-RTT)重新建立与已知主机的连接。
为了解决传输级别的线头阻塞问题,通过 QUIC 连接传输的数据被分为一些流。流是持久性 QUIC 连接中短暂、独立的“子连接”。每个流都处理自己的错误纠正和传递保证,但使用连接全局压缩和加密属性。每个客户端发起的 HTTP 请求都在单独的流上运行,因此丢失数据包不会影响其他流/请求的数据传输。
http 1.0 规定浏览器与服务器保持较短时间的链接,浏览器每次请求都和服务器经过三次握手和慢启动(基本思想是当TCP开始传输数据或发现数据丢失并开始重发时,首先慢慢的对网路实际容量进行试探,避免由于发送了过量的数据而导致阻塞)建立一个TCP链接,服务器完成请求处理后立即断开TCP链接,而且不跟踪每个浏览器的历史请求。
注意:由于http 1.0每次建立TCP链接对性能的影响实在是太大,http1.1实现持久化链接之后,又反向移植到http 1.0上,只是默认是没有开启持久链接的,通过http的header部分的 Connection: KeepAlive 来启用)
请求队列的第一个请求因为服务器正忙(或请求格式问题等其他原因),导致后面的请求被阻塞。
一个TCP链接可以传送多个http请求和相应,减少了TCP建立链接和关闭链接的消耗。另外http1.1允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能 够区分出每次请求的响应内容。
不使用管道的http请求,在使用持久链接时,必须严格满足先进先出的队列顺序(FIFO),即发送请求,等待响应完成,再发送客户端队列中的下一个请求。管道可以让我们把 FIFO 队列从客户端(请求队列)迁移到服务器(响应队列),即客户端可以并行,服务端串行。客户端可以不用等待前一个请求返回,发送请求,但服务器端必须顺序的返回客户端的请求响应结果。
a. 一个请求响应阻塞,就会阻塞后续所有请求
b. 并行处理请求时,服务器必须缓冲管道中的响应,从而占用服务器资源,如果有个响应非常大,则很容易形成服务器的受攻击面;
c. 响应失败可能终止 TCP 连接,从页强迫客户端重新发送对所有后续资源的请求,导致重复处理;
d. 由于可能存在中间代理,因此检测管道兼容性,确保可靠性很重要;
e. 如果中间代理不支持管道,那它可能会中断连接,也可能会把所有请求串联起来。
http1.1 在客户端排队所有请求,然后通过一个TCP持久链接,一个接一个的发送请求(如果有http管道还必须顺序等待服务端的顺序返回结果)。但实际中,浏览器的开发时不会这么笨,浏览器允许我们打开N个TCP链接(大多说浏览器是6个TCP链接,这个数字越大,客户端和服务器的资源占用越多,这个数据也只是感觉安全的数字而已)。
1.更多的套接字会占用客户端、服务器以及代理的资源,包括内存缓冲区和 CPU时钟周期;
2.并行 TCP 流之间竞争共享的带宽;
3.由于处理多个套接字,实现复杂性更高;
4.即使并行 TCP 流,应用的并行能力也受限制。
因此使用多个TCP链接只是权宜之计,后续的http 2.0支持多路复用,很好的解决了上述问题。
举例:
a. 支持Host请求:
b. Connection: 请求头的值为Connection时,客户端通知服务器返回本次请求结果后保持连接;Connection请求头的值为close 时,客户端通知服务器返回本次请求结果后关闭连接
c. 支持断点续传:
d.身份认证:
e.状态管理:
f. 缓存处理:
域名分区是思想是将原来集中到一个服务器上的资源分布到多个服务器上,这样就可以突破浏览器的链接限制(一般是6个),提高并行能力。
代价:
2.必须手工分离一台主机上的资源到多台;.
实际实践中,效果并不是很明显,反而导致被滥用。
目前所有的header请求都是以没有经过压缩的纯文本的形式发送(通常会有600`1000字节),而通常使用的http请求body却很少(10~200字节),和header相比,显得很少,特别是在使用了cookie之后,这样的矛盾就更加突出,因此要减少header的数据。
即将需要多次才能获取的文件或资源组合并成一个,通过一次网络请求获取。这样减少了协议的开销,间接地将服务器端的管道思维移植到了客户端。缺点:增加复杂性,更缓存带来负担,页面的分步显示,改成一次显示,在网络慢的时候影响用户体验。
即将资源嵌入文档(通过URI嵌入图片,音频或PDF),可以减少请求次数。嵌入资源作为页面的返回一部分一次返回,即如果在多个页面中都嵌入同样的资源,那么这个资源将会随着每个页面的加载而被加载,从而增大每个页面的总体大小,如果嵌入资源被更新,客户端只能重新获取有效的资源。
实践:一般只考虑嵌入1~2KB一下的资源
2.如果文件很小,但需要在多个页面中重用,应该考虑集中打包;
HTTP 2.0把解决性能问题的方案内置在了传输层,通过多路复用来减少延迟,通过压缩 HTTP首部降低开销,同时增加请求优先级和服务器端推送的功能。
多路复用允许同时通过单一的 HTTP 2.0 连接发起多重的请求-响应消息,即所有HTTP 2.0 连接都是持久化的,而且客户端与服务器之间也只需要一个连接即可,所有数据流共用同一个连接 ,减少了因http链接多而引起的网络拥塞(在 HTTP1.1 协议中,同一时间,浏览器会针对同一域名下的请求有一定数量限制),解决了慢启动针对突发性和短时性的http链接低效的问题。
即应用层(HTTP)和传输层(TCP or UDP)之间增加一个二进制分帧层,因此在多向请求和响应时,客户端和服务器可以把HTTP消息分解为互不依赖的帧,然后乱序发送,最后再在另一端把它们重新组合起来,解决了http 1.*的对手阻塞问题。
http 2.0支持DEFLATE和HPACK 算法的压缩。
指客户端请求之前发送数据的机制,在 HTTP 2.0 中,服务器可以对客户端的一个请求发送多个响应。
HTTP 2.0 使用一个31比特的优先值,0表示最高优先级, 2(31)-1表示最低优先级,服务器端就可以根据优先级,控制资源分配,优先处理和返回最高优先级的请求帧给客户端。
参考文献:
1.面试时如何优雅的谈论HTTP/1.0/1.1/2.0( http://www.jianshu.com/p/52d86558ca57 )
HTTP 1.0 最早在网页中的使用是在 1996 年,那个时候只是使用一些较为简单的网页和网络请求上,而 HTTP 1.1 则在 1999 年才开始广泛应用于现在的各大浏览器网络请求中,同时 HTTP 1.1 也是当前使用最为广泛的 HTTP 协议。 两者的主要区别体现在:
长连接 : 在 HTTP/1.0 中,默认使用的是短连接,也就是每次请求都要重新建立一次连接。HTTP 是基于 TCP/IP 协议的,每一次建立或者断开连接,都需要三次握手四次挥手的开销,如果每次请求都要这样的话,开销会比较大,因此最好能维持一个长连接,可以用长连接来发多个请求。HTTP 1.1 起,默认使用长连接 Connection: keep-alive 。 HTTP/1.1 的持续连接,有非流水线方式和流水线方式 。流水线方式,是客户在收到 HTTP 的响应报文之前,就能接着发送新的请求报文;与之相对应的非流水线方式,是客户在收到前一个响应后才能发起下一个请求;
错误响应码 :在 HTTP 1.1 中,新增了 24 个错误状态响应码,如 409(Conflict):表示请求的资源与资源的当前状态发生冲突;410(Gone):表示服务器上的某个资源被永久性的删除;
缓存处理 :HTTP 1.0 中,主要使用 header 头里的 If-Modified-Since 、 Expires 来做为缓存判断的标准;HTTP 1.1,则引入了更多的缓存控制策略,如 Entity tag , If-Unmodified-Since , If-Match , If-None-Match 等;
带宽优化及网络连接的使用 :HTTP 1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象传送了过来,并且不支持断点续传功能;HTTP 1.1 中,则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这样方便开发者自由的选择,以便于充分利用带宽和连接。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)