HTTP是Hyper Text Transfer Protocol的缩写。这是一个既古老又现代的协议,完全可以用历久弥新这个词来形容。根据维基百科记载的HTTP History,它最早的文档化的版本是在1991年发布的HTTP v0.9。随后在1996念,正式在IETF发布了RFC 1945,标准化了HTTP/1.0。随后在1999年发布的RFC 2616,对HTTP/1.0做了一个小修改,增加了持久性链接等功能呢,版本升级为HTTP/1.1。

标准新动作

在平静了一段时间之后,HTTP的标准动静又进入了一个小高潮,首先在2014年的时候HTTP/1.1被重新修订,拆分成六个部分,重新发布。这六个部分分别为:

更大的动作在后面,刚修定完HTTP/1.1,在2015年HTTP/2就立马发布了:

  • RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2)
  • RFC 7541: HPACK: Header Compression for HTTP/2

所以现在最新的版本是HTTP/2。

上面说了这么多HTTP的历史,主要是想说明HTTP是一个非常重要、非常有分量的协议,所以HTTP的标准才能获得持续的更新。那HTTP到底如何工作的,它为什么被广泛使用?这是接下来要探讨的话题。

协议的作用

首先需要理解一点,HTTP是一种协议,而协议其实是定义了节点间交互的规则。在设计协议的时候,设计者脑子里面其实是有一个架构的图景,里面有各种各样的节点,以及各个节点之间交互的需求。设计者把这些需求抽象出来,转化成协议中的操作、消息和内容等非常具体的细节,再将这些具体的东西标准化,使之变得通用。这样设计者脑中架构的图景就可以被不同的人不同的方式实现,只要这些不同的实现遵循相应的协议,就可以实现互联互通。

以HTTP为例,它对应的是一个典型的Client和Server的架构,简称CS架构。Client可以是各种常见的浏览器,如Chrome、Firefox等;Server可以是Apache HTTPD,NGINX等。HTTP定义了这些Client和Server如何通信。

HTTP对应的架构

HTTP是一种无状态的协议,它的交互方式是request/reponse,即

Client                Server
   --> HTTP Request
       HTTP Response  <--

交互过程看起来非常简单,对于Client来说,发一条HTTP Request之后,在那等待相应的Response就可以了。对Server来说,处理完回一条HTTP Reqeust,直接返回一条Response即可。HTTP是没有状态的,HTTP Reqeust里面并没有带有序列号之类的信息来和Response关联,所以Request和Response之间的关系是靠时序来保证的。也就是说Client发送了若干条HTTP Request,就会接收到相应条数的Response,而且第一条回来的Response对应第一条发出去的Reqeust。

坏处:消息需要排队

这么做有好有坏,首先来说下坏处是什么。最大的坏处是HTTP消息需要排队,如下所示:

Client                 Server
   --> HTTP Request 1
   --> HTTP Request 2
   --> HTTP Request 3
                       <-- Response 1/Response 2/Response 3

上图中,Client按顺序给Server发送了三条Request消息。假设Server能力很强,很快就把三条Reqeust消息给处理好了,并产生三条Response消息。遗憾的是这三条Response消息并不能同时发送给Client,必须排队,确保Client是按顺序收到这三条Response消息的。

好处:更灵活的架构

以时序来匹配Request/Response的巨大好处是它可以带来更灵活的架构,在Client和Server之间可以引入更多类型的节点。

Gateway

第一种节点类型是Gateway,部署在一个Server群组之前,充当负载均衡或者攻击预防等功能,如下图所示:

                                                          +----------+
                                            +-------------| Server 1 |
                Request                     |             +----------+
   +--------+   ---> 1/2/3  +---------+     | ---> 1/2/3  +----------+
   | Client |---------------| Gateway |-----+-------------| Server 2 |
   +--------+   1/2/3 <---  +---------+     | 1/2/3 <---  +----------+
                Response                    |        
                                            +-------------//////////

Client发送了三条Reqeust消息,分别为1/2/3。Gateway把这个Client的所有消息都转发给Server 2处理。只要Gateway和Server 2是按顺序来处理请求和返回消息的,和Client的交互就不受影响,而Client无需知道是哪个Server处理了请求。

Gatway也可以把Request 1分配给Server 1处理,把Request 2和3分配给Server 2处理。但这样Server 1和Server 2之间必须做同步,保证返回的顺序是1/2/3。

Cache

第二种节点类型是Cache,如下图所示:

                Request         1       Request
   +--------+  ---> 1/2/3   +-------+   ---> 2/3          +---------+
   | Client |---------------| Cache |---------------------| Server  |
   +--------+  1/2/3 <---   +-------+   2/3  <---         +---------+
               Response                Response

Client发送了三条Reqeust消息,分别为1/2/3。由于之前有其他的Client请求过Request 1相同的内容了,在Cache节点上存有备份。所以Cache截获了Request 1,直接返回相应的Response。其他两条Request请求的内容Cache上没有,所以Cache就把Request转给Server,让Server来处理并返回结果。

Cache的实际存在的位置可以有好多种,比如可以在HTTP Proxy上面,也可以直接在本地。

总结和展望

理解协议不能光学习协议定义的消息、字段和交互。搞清楚协议作者脑中的架构图景,可以帮你更好地理解协议的设计,并更好地应用协议。HTTP是一个广泛部署和使用的协议,对HTTP的改进一直在进行中。目前最新的动作是为HTTP 2打造一个全新的传输协议,叫做QUIC,用来替代TCP,有兴趣的读者可以去了解下。