谈谈HTTP
何为HTTP
在这个网络高速发展的时代,不管是我们上网看一篇小说,还是发一条微博,还是完成一次购物,还是看一个直播,背后都离不开HTTP了协议.可以说,没有它,我们就不能互相的联结在一起.
HTTP协议
HTTP是 Hypertext Transfer Protocol 的简称.翻译成中文是超文本传输协议.是由欧洲核子研究委员会(CERN)的蒂姆·伯纳斯 - 李(Tim Berners-Lee)的一位英国工程师发明的.
在1989年发表的一篇论文中,提出了互联网上构建超链接文档系统的构想.这篇论文中他确定了三项关键技术:
-
URI:
Uniform Resource Identifier.统一资源标识符,作为互联网上资源的唯一身份.
延深阅读: Wekipedia上关于URI的说明. -
HTML:
HyperText Makeup Language.超文本标记语言.
关于HTML语法可参照 -
HTTP:
Hypertext Transfer Protocol.超文本传输协议.
以上三项组成了我们熟知的Web,World Wide Web.
HTTP/0.9
20世纪90年代的HTTP被定义为0.9版.结构简单,不支持请求正文,不支持头部,只允许用GET方法从服务器上获取HTML文档,并在响应请求后立即关闭连接.
命令行如下:
GET /index.html
HTTP/1.0
HTTP/1.0版本在1996年发布.和0.9相比,它主要增加了以下几个变化:
- 引入版本号,象征着工程化.(早期的HTTP/0.9是没有版本号.为了区别后来才加上的.)
- 引入了header,把元数据和业务数据解耦.
- 引入了多字符集
- 增加了响应码,让请求双方以及第三方的监控或管理程序有了统一的认识.控制错误和业务错误的分离.
- 增加了HEAD,POST新方法
- 传输的数据不再仅限于文本.可以使用content-Type来传输其他文件.
HTTP/1.0的性能缺陷:
每请求一个资源都要新建一个TCP链接,并且是串行请求.影响网页的打开速度.
但是这时的HTTP/1.0还不是一个标准.
HTTP/1.1
1999年,HTTP/1.1发布了RFC文档,为其确定了编号2616,它是一个正式的标准.
HTTTP/1.1主要解决了HTTP/1.0的网络性能问题,主要变更点有:
- 增加了PUT,DELETE等新方法
- 增加了缓存管理和控制(cache control).
- 明确了链接管理,允许持久连接.
通过设置keepalive来让HTTP重用TCP链接,可以节省TCP三次握手的开销,称为HTTP长链接,HTTP Persistent Connection. - 支持pipeline网络传输.
第一个请求发出后,不必等回来,就可以发送第二个请求,来减少整体的响应时间. - 允许响应数据分块,利于传输大文件.
采用分块传输编码,响应的消息将由若干个块分次传输,而不是一次传回.最后会以一个长度为0的块和一个空行,来表示传输完毕.这种技术又叫做服务端Push模型. - 强制要求Host头,让互联网主机托管成为可能.
因为可以有多个域名解析到一个IP上,加上HOST头后,服务器就知道你要请求哪个网站. - 协议头增加了Language,Encoding,Type等.
在2014年,HTTP/1.1又做了一次修订.原来的一个大文档被分成了六个小文档(7230-7235),优化了细节.
在介绍HTTP/2.0之前,让我们先来看看一个HTTP请求到底是什么样子的.
1.构建HTTP请求
打开命令行,输入:
telent www.google.com 80
会显示:
Trying 172.217.161.228... Connected to www.google.com. Escape character is '^]'.
接着输入以下请求:
GET / HTTP/1.1 Host:www.google.com User-Agent:Mozila/1.22 Connection:keep-alive Accept:text/html
HTTP协议是基于TCP协议的,使用面向连接的方式发送请求.通过stream二进制流的方式传给对方.下面是得到Google的回应:
HTTP/1.1 200 OK Date: Thu, 16 Jan 2020 12:16:01 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info." Server: gws X-XSS-Protection: 0 X-Frame-Options: SAMEORIGIN Set-Cookie: 1P_JAR=2020-01-16-12; expires=Sat, 15-Feb-2020 12:16:01 GMT; path=/; domain=.google.com; Secure Set-Cookie: NID=196=JN76tY2TOSKUHfy8MKnwsx2iWggCb52KXI7JYFydFC408Mrd1K0fN3wCjxgsL3juw-qmUPlRIfMaAsi-UOAeFPUyGLB0Ma56o878yThR3hZbJaBUxgy9hvs7hUCFV_CXNX_GsUU9v8u4qIO-BiP-uDuGpCaeVjIJV_ab9s2ZkPg; expires=Fri, 17-Jul-2020 12:16:01 GMT; path=/; domain=.google.com; HttpOnly Accept-Ranges: none Vary: Accept-Encoding Transfer-Encoding: chunked 32cc ...(html) 0 Connection closed by foreign host.
从上面可以看出,HTTP返回报文的格式:
- 状态行:版本号,状态码,短语 cr lf
- 首部:首部字段名:字段值(复数) cr lf cr lf
- 实体
HTTP/2.0
虽然HTTP/1.1在网络性能上解决了许多问题,但是数据传输成本大(借助消耗CPU的压缩减少带宽),请求的串行发送的一些特点却没有改变.
Google开发自己的浏览器Chrome,推出了新的SPDY协议.互联网标准化组织以SPDY协议为基础,在2015年发布了HTTP/2,RFC编号为7540.
HTTP/2.0的主要特点:
- 二进制格式编码,不再是纯文本.增加了传输的效率.
常见的又Header帧,用于传输Header内容,并且会开始一个新的流.然后是Data流,用于传输正文实体.多个Data帧属于同一个流.
图片引用于<极客时间 刘超老师的 趣谈网络协议之HTTP协议> - 可发起多个请求,废弃了1.1的管道.
- 使用专用算法压缩头部,减少数据传输量.使用HPACK算法.
- 允许服务器主动向客户端推送(服务端PUSH)数据.
没有请求的东西,服务端也可以先送给你放在你的本地缓存中. - 增强了安全性,要求加密通信.
HTTP/2.0的这些特点,使在性能上有很大的提高.
HTTP/3.0
不管是HTTP/1.1,还是HTTP/2.0,其主要的性能问题还是,若干个HTTP的请求复用一个TCP链接,底层的TCP协议是不知道上层有多少个HTTP请求的.一旦丢包,就会造成所有的HTTP请求必须等待丢包被重传回来.
这个问题又叫做Head-of-Line Blocking问题.
Google又发明了一个新的协议,叫做QUIC,把HTTP的底层协议改成了UDP.
QUIC的特点:
- 自定义连接机制
采用64位随机ID作为标识,解决了一条TCP连接的四元标识(源IP,源端口,目的IP,目的端口),一个元标识改变就要重连的问题. - 自定义重传机制
定义offset概念,QUIC有个序列号是递增的.发送的数据在数据流里面有个偏移量offset.通过offset查看数据发送到哪里,如果offset包没有到达,就重发.到了,就拼接. - 多路复用
同一条QUIC连接上可以创建多个stream,来发送多个HTTP请求. - 自定义流量控制
通过window_update,来告诉对端可以接收的字节数. - 把TCP和TLS合并成三次握手
QUIC是一个在UDP上的伪TCP+TLS+HTTP/2的多路复用协议
在2018年,互联网标准化组织 IETF 提议将“HTTP over QUIC”更名为“HTTP/3”并获得批准,HTTP/3 正式进入了标准化制订阶段.
或许不久的将来,我们就可以大规模的使用HTTP/3.0了吧.
参考: