前端面经-操作系统与网络原理
HTTP1.0
早先1.0
的HTTP
版本,是一种无状态、无连接的应用层协议。
HTTP1.0
规定浏览器和服务器保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP
连接,服务器处理完成后立即断开TCP
连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态)。
这种无状态性可以借助cookie/session
机制来做身份认证和状态记录。而下面两个问题就比较麻烦了。
首先,无连接的特性导致最大的性能缺陷就是无法复用连接。每次发送请求的时候,都需要进行一次TCP
的连接,而TCP
的连接释放过程又是比较费事的。这种无连接的特性会使得网络的利用率非常低。
其次就是队头阻塞(head of line blocking
)。由于HTTP1.0
规定下一个请求必须在前一个请求响应到达之前才能发送。假设前一个请求响应一直不到达,那么下一个请求就不发送,同样的后面的请求也给阻塞了。
为了解决这些问题,HTTP1.1
出现了。
HTTP1.1
对于HTTP1.1
,不仅继承了HTTP1.0
简单的特点,还克服了诸多HTTP1.0
性能上的问题。
-
首先是长连接,
HTTP1.1
增加了一个Connection
字段,通过设置Keep-Alive
可以保持HTTP
连接不断开,避免了每次客户端与服务器请求都要重复建立释放建立TCP
连接,提高了网络的利用率。如果客户端想关闭HTTP
连接,可以在请求头中携带Connection: false
来告知服务器关闭请求。 -
其次,是
HTTP1.1
支持请求管道化(pipelining
)。基于HTTP1.1
的长连接,使得请求管线化成为可能。管线化使得请求能够“并行”传输。举个例子来说,假如响应的主体是一个html
页面,页面中包含了很多img
,这个时候keep-alive
就起了很大的作用,能够进行“并行”发送多个请求。(注意这里的“并行”并不是真正意义上的并行传输,具体解释如下。)
需要注意的是,服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容。
也就是说,HTTP
管道化可以让我们把先进先出队列从客户端(请求队列)迁移到服务端(响应队列)。
如图所示,客户端同时发了两个请求分别来获取html
和css
,假如说服务器的css
资源先准备就绪,服务器也会先发送html
再发送css
。
换句话来说,只有等到html
响应的资源完全传输完毕后,css
响应的资源才能开始传输。也就是说,不允许同时存在两个并行的响应。
可见,HTTP1.1
还是无法解决队头阻塞(head of line blocking
)的问题。同时“管道化”技术存在各种各样的问题,所以很多浏览器要么根本不支持它,要么就直接默认关闭,并且开启的条件很苛刻…而且实际上好像并没有什么用处。
-
缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag
If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
-
带宽优化及网络连接的使用,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且
支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者
由的选择以便于充分利用带宽和连接。
-
错误通知的管理,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务
上的某个资源被永久性的删除。
-
Host头处理,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技
的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应
持Host头