超文本传输​​协议(HTTP)是互联网上最普遍并广泛采用的应用协议之一:它是客户端和服务器之间的通用语言,促成了现代网络的形成。最开始它以单关键字和文档路径的简单形式出现,目前已成为不仅仅是浏览器,几乎每个互联网连接的软件和硬件应用程序所选择的协议。

在本章中,我们将简要介绍HTTP协议的演进。对不同HTTP语义的完整讨论超出了本书的范围,但是了解HTTP的关键设计变更及其背后的动机将为我们讨论HTTP性能提供必要的知识储备,特别是在许多即将到来的HTTP/2改进的背景下。

HTTP0.9:单线协议

Tim Berners-Lee提出最初的HTTP提案设计时,考虑到了其简单性,这帮助了他采用他的新想法:万维网。似乎策略被应用之后,这位有抱负的协议设计者才进入大家的视野。

1991年,Berners-Lee概述了新协议的动机,列出了几个高级设计目标:文件传输,对超文本进行索引搜索并将其存档,格式协商以及由客户端向服务器发出请求。为了切实地证明理论,Berners-Lee建立了一个简单的原型,实现了所提出的功能的一小部分:

  • 客户端请求是单个ASCII字符串。

  • 客户端请求由回车(CRLF)终止。

  • 服务器响应是一个ASCII字符流。

  • 服务器响应是一种超文本标记语言(HTML)。

  • 文档传输完成后,连接终止。

然而,即使这听起来比它实际更复杂。这些规则支持的是一个非常简单的,对Telnet友好的协议,一些Web服务器很快就能支持它:

$> telnet google.com 80

Connected to 74.125.xxx.xxx

GET /about/

(hypertext response)
(connection closed)

请求由单行:GET方法和所请求文档的路径组成。响应是单个超文本文档 - 没有头或任何其他元数据,只是HTML。它真的再简单不过了。此外,由于先前的交互是预协议的子集,所以它非正式地获取HTTP 0.9标签。众所周知,一些协议子集已成为历史。
1991年HTTP初具雏形,HTTP接受了自己的生活,并在未来几年迅速发展。让我们快速回顾一下HTTP 0.9的特性:

  • 客户端 - 服务器,请求 - 响应协议。

  • 通过TCP / IP链路运行的ASCII协议。

  • 被设计用于传输超文本文件(HTML)。

  • 每次请求后,服务器和客户端之间的连接关闭。

流行的Web服务器,如Apache和Nginx,仍然支持部分的HTTP0.9协议(HTTP0.9内容并不多)。如果你好奇,打开Telnet会话,并尝试通过HTTP 0.9访问google.com或您自己喜欢的网站,并查看此早期协议的行为和局限性。

HTTP / 1.0:快速生长和信息RFC
1991年到1995年是HTML规范(一种被称为“网络浏览器”的新型软件)和 以消费者为导向的公共互联网基础设施的快速协同增长时期。

完美风暴:在20世纪90年代早期的互联网热潮

基于Tim Berner-Lee的浏览器原型,国家超级计算应用中心(NCSA)的一个团队决定实施自己的版本。这样,第一个流行的浏览器NCSA Mosaic诞生了。NCSA团队的一名程序员Marc Andreessen与Jim Clark合作,于1994年10月成立了Mosaic通讯公司,后来更名为Netscape,并于1994年12月发布了Netscape Navigator 1.0。至此,万维网在大家心中的意义已经不仅限于学术上的探索。

事实上,同年在瑞士日内瓦举办了第一次万维网会议,会议上万维网联盟(W3C)创建,以帮助指导HTML的发展。与此同时,在IETF内部建立并行的HTTP工作组(HTTP-WG)也致力于HTTP协议的改进。这两个组织持续推动了网络的发展。

最后,这场完美的风暴中,还有一个重大举措:CompuServe,AOL和Prodigy在1994 - 1995年的同一时间段内开始向公众提供拨号上网。在技术快速变现的浪潮中,Netscape在1995年8月9日成功举办了一次非常成功的IPO,互联网热潮已经到来,每个人都想参与其中!

HTTP 0.9并不能很好地满足新兴网络的需求,并且实际的使用也暴露了HTTP 0.9的许多基本限制:我们需要一个协议,不仅可以服务于超文本文档,还可以提供更多关于请求的元数据响应,启用内容协商等。而在实际应用中,网络开发人员的新生社区通过大家共同推动的过程,生成了大量实验性HTTP服务器和客户端,通过这些实验性的实施部署查看用户的使用倾向。

从这个社区积极推动的实验时期开始,出现了一套最佳做法和常见模式,1996年5月,HTTP工作组(HTTP-WG)发布了RFC 1945,该文件记录了许多最后在HTTP / 1.0中被采用的野生用法。请注意,这只是一些信息汇总RFC:HTTP / 1.0,我们知道它不是正式规范或Internet标准!

话虽如此,HTTP / 1.0的示例应该看起来很熟悉:

$> telnet website.org 80
Connected to xxx.xxx.xxx.xxx

GET /rfc/rfc1945.txt HTTP/1.0  //请求行与HTTP版本号,后跟请求头
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
Accept: */ *

HTTP/1.0 200 OK  //响应状态,后跟响应头
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 01 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 1 May 1996 12:45:26 GMT
Server: Apache 0.84

(plain-text response)
(connection closed)

上述消息机制不是HTTP / 1.0功能的详尽列表,但它说明了一些关键协议更改:

  • 请求可能包含多个换行标题字段。

  • 响应对象以响应状态行为前缀。

  • 响应对象有自己的一行以换行符分隔的头部。

  • 响应对象不限于超文本。

  • 每个请求后,服务器和客户端之间的连接关闭。

请求头和响应头都保存为ASCII编码,但响应对象本身可以是任何类型:HTML文件,纯文本文件,图像或任何其他内容类型。因此,HTTP的“超文本传输​​”部分在引入后不久很容易被人们误会。在现实中,HTTP已迅速发展成为一个超媒体传输,但原来的名字依旧被保留。

除媒体类型协商外,RFC还记录了许多其他常用功能:内容编码,字符集支持,多类型,授权,缓存,代理行为,日期格式等。

今天,网络上几乎每个服务器仍是以HTTP / 1.0的协议传输的。除此之外,你应该很清楚!每个请求都要有新的TCP连接,对HTTP / 1.0是很大的性能损失; 参见三次握手,还有慢启动

HTTP / 1.1:互联网标准

从1995年至1999年,HTTP / 1.0的文档化在逐步推进,历时4年,HTTP成为官方IETF互联网的标准。事实上,大约在HTTP / 1.0发布后六个月,第一个官方HTTP / 1.1标准定义在RFC 2068中,于1997年1月就正式发布。两年半后,1999年6月,一些改进和更新被纳入标准,并作为RFC 2616发布。

HTTP / 1.1标准规范了许多早期版本中的不清晰的协议内容,并引入了很多关键性能优化:持续连接,分块编码传输,以字节为单位的请求,另外还有缓存机制,传输编码和请求管线化(多个HTTP请求整批提交的技术)。

有了这些功能,我们现在可以通过在任何现代浏览器和客户端运用HTTP,观察典型的HTTP / 1.1会话:

$> telnet website.org 80
Connected to xxx.xxx.xxx.xxx

GET /index.html HTTP/1.1  //请求HTML文件,其中包含编码,字符集和Cookie元数据
Host: website.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=P0-800083390... (snip)

HTTP/1.1 200 OK  //针对原始HTML请求的分块响应
Server: nginx/1.0.11
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Via: HTTP/1.1 GWA
Date: Wed, 25 Jul 2012 20:23:35 GMT
Expires: Wed, 25 Jul 2012 20:23:35 GMT
Cache-Control: max-age=0, no-cache
Transfer-Encoding: chunked

100  //块中的八位字节数以ASCII十六进制数表示(256字节)
<!doctype html>
(snip)

100
(snip)

0  //分块流响应结束

GET /favicon.ico HTTP/1.1  //请求在同一个TCP连接上图标文件
Host: www.website.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
Accept: */ *
Referer: http://website.org/
Connection: close  //通知服务器连接不会被重用
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=P0-800083390... (snip)

HTTP/1.1 200 OK  //图标响应,之后连接关闭
Server: nginx/1.0.11
Content-Type: image/x-icon
Content-Length: 3638
Connection: close
Last-Modified: Thu, 19 Jul 2012 17:51:44 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes
Via: HTTP/1.1 GWA
Date: Sat, 21 Jul 2012 21:35:22 GMT
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Etag: W/PSA-GAu26oXbDi

(icon data)
(connection closed)

呃,这期间其实发生了很多事情!第一个也是最明显的区别是,我们有两个对象请求,一个用于HTML页面,另一个用于图像,两者都通过单个连接传递。每次连接都是持续的,这允许我们重复使用现有的TCP连接实现多个请求到相同的主机,并提供更快的终端用户体验; 参阅优化TCP

要终止持久连接,你将会注意到,第二客户端在请求的连接头中发送了显式关闭令牌到服务器。类似地,服务器可以在传输响应时,通知客户端它意图关闭当前TCP连接。从技术上讲,任何一方都可以在任何时候终止TCP连接而无需这种信号,但客户端和服务器应尽可能提供它,以便使双方实现更好的连接重用策略。

默认情况下,HTTP / 1.1使用持续链接,这是在HTTP协议语义上做出的更改。这意味着,除非另行告知(通过 Connection: close头),服务器应该保持连接默认打开。

然而,这种相同的功能通过启用Connection: Keep-Alive报头,也被反向移植到HTTP / 1.0。因此,如果你正在使用HTTP / 1.1,在技术上你不需要的 Connection: Keep-Alive头,但许多客户选择仍然提供。

此外,HTTP / 1.1协议添加了内容,编码,字符集,甚至语言协商,传输编码,缓存指令,客户端cookie,以及可以在每个请求上协商的十几个其他功能。

我们不会讲述每个HTTP / 1.1功能的语义。这是一本专门的HTTP协议书该做的,许多伟大的书已经做得很好。而且,前面的例子很好地说明了HTTP的快速进展和进化,以及每个客户端 - 服务器错综复杂的优雅信息交换机制。那里有很多地方值得探索!

推荐一个有关HTTP协议所有工作机制的参考:O’Reilly’s HTTP: David Gourley 和 Brian Totty 写的权威指南.

HTTP / 2:提高传输性能

自从问世以来,RFC 2616已经成为互联网前所未有的发展基础:数十亿种各种形状和大小的设备,从台式电脑到我们口袋里的小型网络设备,每天都会传出HTTP,它提供新闻,视频,以及数百万其他我们生活中依赖的网络应用程序。

最开始的一个简单的单行协议检索超文本快速演变成​​一个通用的超媒体传输,十年以后的现在,它可以用来满足任何你可以想象的使用场景。可以说服务器使用协议之普遍,用户在客户端的使用之广泛,意味着许多应用程序现在是专门设计和部署在HTTP之上的。

需要一个协议来控制你的咖啡壶?RFC 2324已经覆盖了超文本咖啡壶控制协议(HTCPCP / 1.0) - 这是最初是IETF的愚人节玩笑,超链接为我们打开了新世界的大门。

超文本传输​​协议(HTTP)是用于分布式,协作的超媒体信息系统的应用级协议。它是一种通用的,无状态的协议,可以通过扩展其请求方法,错误代码和头部信息,将其用于许多超出超文本使用的任务,如域名解析和分布式对象管理系统。HTTP的一个特征是数据表示的归类和协商,允许系统独立于要传输的数据。RFC 2616:HTTP / 1.1,1999年6月

HTTP协议的简单性使其最初可以被采用并且能够快速发展。事实上,现在在嵌入式设备 - 传感器,执行器和咖啡壶中,使用HTTP作为主要协议进行数据控制是很普遍的。但是,在如此的重大成功之下,随着我们越来越多的社交,电子邮件,新闻和视频等日常互动的网络化,以及越来越多的个人和工作空间,HTTP协议面临着压力。用户和Web开发人员需要应用的实时响应,也就是高性能协议,仅在HTTP / 1.1基础上进行修改是不能满足需求的。

为了应对这些新的挑战,HTTP必须继续发展,因此,HTTPbis工作组在2012年初发布了一个新的HTTP / 2计划:

在协议中有新的实现经验和关注点,该协议保留了HTTP的语义,而没有HTTP / 1.x消息框架和语法的遗留,因为它们影响性能并鼓励滥用底层传输。

工作组将以有序的双向流的形式给出HTTP当前语义的新表达式规范。与HTTP / 1.x一样,主要采用TCP,也可以使用其他传输。

HTTP / 2章程,2012年1月

HTTP / 2的主要重点是改善传输性能​​,同时实现更低的延迟和更高的吞吐量。主要版本的更新听起来跨度很大,它在性能方面的确有很多改善,但值得注意的是,没有一个高级协议语义受到影响:所有HTTP头,值和用例是相同的。

任何现有的网站或应用程序都可以通过HTTP / 2进行交付,无需修改:您不需要修改应用程序标记,以利用HTTP / 2。HTTP服务器将不得不升级为HTTP / 2,但这应该是对大多数用户的透明升级。唯一的区别,如果工作组达到其目标,我们的应用程序交付将要具有更低的延迟和更好网络链接利用!

话虽如此,别高兴得太早。在我们获得新的HTTP / 2协议功能之前,应该退一步,总结我们现有的HTTP / 1.1的部署和性能最佳实践。HTTP / 2工作组正在快速推出新规范,但即使最终标准已经完成并准备就绪,我们仍然可以在可预见的将来支持较旧的HTTP / 1.1客户端。


爱睡觉的小猫咪
310 声望22 粉丝

勤奋的小前端