HTTP协议是因特网的多媒体信使。HTTP能够从遍及世界的Web服务器上将这些信息快迅速,便捷,可靠地搬移到人们桌面上的Web浏览器上去。git
HTTP协议主要分Web客户端和服务器。其中Web服务器是Web资源的宿主。Web资源能够包含任意媒体类型内容,HTTP协议为了标识各类媒体类型,会给经过Web传输的对象都打上MIME类型的数据标签格式。(MIME科普:最初设计MIME(Multipurpose Internet Mail Extension
,多用途因特网邮件扩展)是为了解决在不一样的电子邮件系统之间搬移报文时存在的问题。HTTP随后也采用了它,用他来描述并标记多媒体内容。)github
同时,每一个web服务器资源都有一个名字去标识,这被称为统一资源标识符(Uniform Resource Identifier
)。URI有两种类型,一种是咱们常见的统一资源定位符URL,另一种被称为统一资源名URN。后者仍处于试验阶段,未大范围使用。web
web页面能够包含多个对象,如一个页面会包括许多图片,视频,音频等内容。客户端经过向Web服务器发送请求命令来进行事务处理。服务器响应客户端请求,并传送相应数据。算法
请求和响应报文都有固定的规范。报文由一行一行简单字符串组成的。HTTP报文都是纯文本,而不是二进制代码,因此人们能够很方便的进行读写(但难以解析)。报文分为三部分浏览器
起始行 GET /index.html HTTP/1.0
缓存
首部字段 每一个首部字段包含一个名字和一个值,为了便于解析,二者之间用冒号来分割。首部以一个空行结束。性能优化
主体 起始行和首部都是文本形式且都是结构化的,主体则能够包含任意的二进制数据,固然也能够包含文本。服务器
HTTP协议的报文是经过传输控制协议(Transmission Control Protocol,TCP
)链接从一个地方搬移到另一个地方去的。
TCP提供了网络
无差错的数据传输
按序传输 (数据老是会按照发送的顺序到达)
未分段的数据流 (能够在任意时刻以任意尺寸将数据发送出去)
在HTTP客户端向服务器发送报文以前,须要用网际协议(Internet Protocol,IP
)地址和端口号在客户端和服务器之间创建一条TCP/IP链接。首先须要将URL进行DNS解析成IP地址,再用IP地址链接Web服务器,默认端口是80。
除了客户端与服务器以外,还有许多比较重要的Web结构组件
代理 位于客户端和服务器之间的HTTP中间实体
缓存 HTTP的仓库,使经常使用页面的副本能够保存在离客户端更近的地方
网关 链接其余应用程序的特殊Web服务器
隧道 对HTTP通讯报文进行盲转发的特殊代理
Agent代理 发起自动HTTP请求的半智能Web客户端
URL提供了一种统一的资源命名方式,大多数URL都有一样的:"方案://服务器位置/路径"结构。
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
几乎没有哪一个URL包含了全部这些组件。
URL最重要的3个部分是方案(scheme
),主机(host
)和路径(path
)。
转义表示法包含一个百分号%,后面跟着两个表示字符ASCII码的十六进制数。
例子http://www.baidu.com/%7Ejoe
~ 126(0x7E)
HTTP报文是在HTTP应用程序之间发生的数据块。这些数据块以一些文本形式的元信息(meta-information
)开头,这些信息描述了报文的内容及含义,后面跟着可选的数据部分。这些报文在客户端,服务器和代理之间流动。
全部的报文均可以分为两类:请求报文(request message
)和响应报文(response message
)。
请求报文
<method> <request-URL> <version> <headers> <entity-body>
响应报文
<version> <status> <reason-phrase> <headers> <entity-body>
方法 | 描述 |
---|---|
GET | 从服务器获取一份文档 |
HEAD | 只从服务器获取文档的首部 |
POST | 向服务器发送须要处理的数据 |
PUT | 将请求的主体部分存储在服务器上 |
PUT | 对可能通过代理服务器传送到服务器上去的报文进行追踪 |
OPTIONS | 决定能够在服务器上执行哪些方法 |
DELETE | 从服务器上删除一份文档 |
并非全部服务器都实现了上述7种方法,并且,因为HTTP设计的易于扩展,因此其余服务器可能还会实现一些本身的请求方法。
总体范围 | 已定义范围 | 分类 |
---|---|---|
100 ~ 199 | 100~101 | 信息提示 |
200~299 | 200~206 | 成功 |
300~399 | 300~305 | 重定向 |
400~499 | 400~415 | 客户端错误 |
500~599 | 500~505 | 服务器错误 |
当前的HTTP版本只为每类状态定义了几个代码,随着协议的发展,HTTP规范中会正式的定义更多的状态码,若是收到了不认识的状态码,多是有人将其做为当前协议的扩展定义的。能够根据其所处范围,将它做为那个类别中一个普通的成员来处理。
首部分类:
通用首部 既能够出如今请求报文中又能够出如今响应报文中
请求首部 提供更多有关请求的信息
响应首部 提供更多有关响应的信息
实体首部 描述主体的长度和内容,或者资源自身
扩展首部 规范中没有定义的新首部
HTTP报文的第三部分是可选的实体主体部分。实体的主体是HTTP报文的负荷,就是HTTP要传输的内容。
世界上几乎全部的HTTP通讯都是由TCP/IP承载的,TCP/IP是全球计算机及网络设备都在使用的一种经常使用的分组交换网络分层协议集。客户端应用程序能够打开一条TCP/IP链接,链接到可能运行在世界任何地方的服务器应用程序。
https://github.com:80/WilsonLiu95
浏览器利用解析出主机名 github.com
浏览器查询这个主机名的IP地址 192.30.252.122
浏览器得到端口号 80
浏览器发起到192.30.252.122
端口80的链接
浏览器向服务器发送一条HTTP GET报文
浏览器从服务器读取HTTP响应报文
浏览器关闭TCP链接
与创建TCP链接,以及传输请求和响应报文的时间相比,事务处理时间多是很短的。除非客户端或服务器超载,或正在处理复杂的动态资源,不然HTTP时延就是由TCP网络时延构成的。
HTTP事务时延的有如下几种主要缘由
客户端首先须要根据URI肯定Web服务器的IP地址和端口号。其中IP地址须要经过DNS解析URL中的主机名得到,这可能花费数十秒的时间。
客户端向服务器发送TCP链接请求,即著名的"三次握手"。这个值一般最多只有一两秒钟,但若是有数百个HTTP事务的话,这个值就会快速叠加上去。
因特网传输报文,以及服务器处理请求报文都须要花费时间。
web服务器回送HTTP响应也须要时间。
这些TCP网络时延取决于硬件速度,网络和服务器的负载,请求和响应报文的尺寸,以及客户端和服务器之间的距离。TCP协议的技术复杂性也会对时延产生巨大的影响。
一下是其他一些会对HTTP产生影响,最多见的相关时延
TCP链接创建握手
TCP慢启动拥塞控制
数据聚焦的Nagle算法
用于捎带确认的TCP延迟确认算法
TIME_WAIT时延和端口耗尽
TCP链接握手须要通过一下几个步骤
酷虎的向服务器发送一个小的TCP分组(一般是40-60字节)。这个分组中设置了一个特殊的SYN标记,说明这是一个链接请求。
若是服务器接收了链接,就会对一些链接参数进行计算,并向客户端回送一个TCP分组,这个分组中的SYN和ACK标记都被置位了,说明链接请求已经被接收了。
最后,客户端向服务器回送一条确认信息,通知它链接已成功创建。现代的TCP栈都容许客户端在这个确认分组中发送数据。
若是链接只用来传送少许的数据,这些交换过程就会严重下降HTTP的性能。小的HTTP事务可能会在TCP创建上花费50%或者更多的时间。
每一个TCP段都有一个序列号和数据完整性校验和。每一个段的接收者收到无缺的段时,都会向发送者回送小的确认分组。若是发送者没有在指定的窗口时间内收到确认信息,发送者就认为分为已被破坏或损毁,并重发数据。
为了增长确认报文找到同向传输数据分组的可能性,不少TCP栈都实现了一种"延迟确认"算法。延迟确认算法会在一个特定的窗口时间(一般是100~200毫秒)内将输出确认存放在缓冲区中,以寻找可以捎带它的输出数据分组。若是在那个时间段内没有输出数据分组,就讲确认信息放在单独的分组中传送。
一般,延迟确认算法会引入至关大的时延,因此能够调整或者禁止延迟确认算法。
TCP数据传输的性能还取决于TCP链接的使用期(age
)。TCP链接会随着时间进行自我“调谐”,起初会限制链接的最大速度,若是数据成功传输,会随着时间的推移提升传输的速度。这种调谐被称为TCP慢启动(slow start
),用于防止因特网的忽然过载和拥塞。
Nagle算法鼓励发送全尺寸(LAN上最大尺寸的分组大约是1500字节,在因特网上是几百字节)的段。只有当全部其余的分组都被确认以后,Nagle才容许发送非全尺寸的分组,若是其余分仍然在传输过程当中,就将那部分数据缓存起来。只有当挂起分组被确认,或者缓存中积累了足够发送一个全尺寸分组的数据时,才会将缓存的数据发送出去。
Nagle算法会引起几种HTTP性能问题。首先小的HTTP报文没法填满一个分组,可能会由于等待那些永远不会到来的额外数据而产生时延。其次,Nagle算法与延时确认之间的交互存在问题——Nagle会阻止数据的发送,直到有确认分组抵达为止,但确认分组自身会被延迟确认算法延迟100-200毫秒。
所以,HTTP应用程序经常会在本身的栈中设置参数TCP_NODELAY,禁用Nagle算法,提升性能。
当某个TCP端点关闭TCP链接时,会在内存中维护一个小的控制块,用来记录最近所关闭链接的IP地址和端口号。这类信息会维持一小段时间,以确保在这段时间内不会建立于相同地址和端口号的新链接。
客户端每次链接到服务器上去时,都会得到一个新的端口号,以实现链接的惟一性。但因为可用的源端口数量有限,所以会出现端口耗尽的状况。就会没法创建新的链接。
解决办法:增长客户端负载生成机器的数量,或者确保客户端和服务器在循环使用几个虚拟的IP地址以增长更多的链接组合。
HTTP容许在客户端和最终的源端服务器之间存在一串HTTP中间实体(代理,高速缓存等)。能够从客户端开始,逐跳地将HTTP报文通过这些中间设备,转发到源端服务器上去(或者进行反向传输)。
在某些状况下,两个相邻的HTTP应用程序会为它们共享的链接应用一组选项。HTTP的Connection首部字段中有一个由逗号分隔的链接标签列表,这些标签为此链接指定了一些不会传播到其余链接中去的选项。
Connection首部能够承载3种不一样类型的标签
HTTP首部字段名,列出了只与此链接有关的首部
任意标签值,用于描述此链接的非标准选项
值close,说明操做完成以后需关闭这条持久链接
若是支队链接进行简单的管理,TCP的性能时延可能会叠加起来。串行加载的另一个缺点是,有些浏览器在对象加载完毕以前没法获知对象的尺寸,并且它们可能须要尺寸信息来决定将对象放在屏幕的什么位置上,因此在加载了足够多的对象以前,没法在屏幕上显示任何内容。
如下为4种提升HTTP链接性能的技术。
并行链接 经过多条TCP链接发起并发的HTTP请求
持久链接 重用TCP链接,以消除链接及关闭时延
管道化链接 经过共享的TCP链接发起并发的HTTP请求
复用的链接 交替传送请求和响应报文 (实验阶段)
HTTP容许客户端打开多条链接,并行地执行多个HTTP事务。
并行链接能够提升符合页面的传输速度,但并行链接也有一些缺点:
每一个事务都会打开/关闭一条新的链接,好耗费时间和带宽
因为TCP慢启动特性的存在,每条新链接的性能会有所下降
可打开的并行链接数量其实是有限的
Web客户端常常会打开到同一个站点的链接。所以,初始化了对某服务器的HTTP请求的应用程序极可能会在不久的未来对那台服务器发起更多的请求。这种性质被称为站点局部性。
所以,HTTP/1.1容许HTTP设备在事务处理结束以后将TCP链接保持在打开状态,以便为未来的HTTP请求重用现存的链接。
在事务处理结束以后仍然保持在打开状态的TCP链接被称为持久链接。非持久链接会在每一个事务结束以后关闭。持久链接会在不一样事务之间保持打开状态,直到客户端或服务器决定将其关闭为止。
重用已对目标服务器打开的空闲持久链接,就能够避开缓慢的链接创建阶段。并且,已经打开的链接还能够避免慢启动的拥塞适应阶段,以便更快速地进行数据的传输。
持久链接有一些比并行链接更好的地方。持久链接下降了时延和链接创建的开销,将链接保持在已调谐状态,并且减小了打开链接的潜在数量。(持久链接有两种类型:比较老的HTTP/1.0+ "keep-alive"链接,以及现代的HTTP/1.1 "persistent"链接)
并行链接与持久链接配合使用多是最高效的方式。
容许在持久链接上可选的使用请求管道,这是相对于keep-alive
链接的又一性能优化。
在响应到达以前,能够将多条请求放入队列。当第一条请求经过网络流向地球另外一端的服务器时,第二条和第三条请求也能够开始发送了。在高时延网络条件下,这样作能够下降网络的环回时间。
本文为《http权威指南》的第一部分,由第一到四章组成,介绍了HTTP的基础构件和HTTP的核心技术。但愿你们可以喜欢。