网络协议之万维网摇篮 - Http
凡是与电脑打交道的人,每天必然会用浏览器,只要用了浏览器就需要输入一个网址。这个网址的样子是这样的: “http://”, 没错,它就是这篇文章的主人公。它是如此的熟悉,以致于我们会忽略它的存在.
它的前世今生到底是什么样子?
- 背景
- http发展历史
- 未来
背景
1965年8月24日,Ted Nelson发表在美国计算机协会(ACM)上的论文,用到了词语
“hypertext”. 这里的超文本和我们现在说的超文本内涵是不一样的.
1989年, 当时在 CERN 工作的 Tim Berners-Lee 博士写了一份关于建立一个通过网络传输超文本系统的报告。这个系统起初被命名为 Mesh。 在随后的1990年项目实施期间被更名为万维网(World Wide Web). 它有四个部分组成
- HTML - 一种用来表示超文本的格式
- HTTP - 用来传输超文本的协议
- 网页浏览器 - WorldWideWeb, 显示超文本的软件。可以打开地址,体验一下第一款网络浏览器.
- 服务器 - CERN httpd.
从这里我们可以看到
- HTML是一种文档格式。再看看现在的Html5,这种变化是相当相当的巨大.
- Http不干别的,就是用来显示文档的.
- 第一个网页浏览器
- 第一个web服务器
- 这里没有JS. 换句话说,不能和网页有交互.
- 这里没有CSS. 换句话说,浏览器的内容没有那么美
我们应当记住这个时间点,在这个时间点上出现了好多第一。而且也应该知道,出现这些东西是简单的和朴素的。这个世界是变幻莫测的,有哪几股力量导致了http, html 变成了今天这个样子?
Http发展历史
Http/0.9 - 小学生
Http/0.9在1991年发布。 它是简单的。 它只支持
- get方法。
- 只能返回Html格式的文件.
也没有错误码,如果发送错误,返回一个错误的Html就可以了. Http 0.9真的可以说是技能单一。
Http/1.0 - 中学生
Http/1.0在1996年5月发布,它是http0.9的升级版。 它的能力相比0.9就强多了
- 支持状态码
- 支持多种格式的文档返回类型
- 缓存 - Expires, Pragma
- Keep-alive - 需要显示指定。 默认是短连接
- Http头
- 新的Http方法 - HEAD, POST。 至此,前端开发中最常用的Get, Post方法已经全了
Http/1.0 存在的问题
- 连接无法复用 - 每次通信都是遵循打开连接,接受数据,关闭连接这个过程。这就导致了效率非常低下
Http/1.1 - 大学生
1997年处,Http/1.1发布. Http/1.1的特性在整个Http历史上是革命性的,如同Jquery之于前端, Spring之于Java.
来看看Http/1.1可以做什么
- 持久连接 - 默认支持长连接
- pipelining机制 - 客户端同时按顺序发送多个连接,服务端按顺序返回多个响应
- 新增Http方法 - OPTIONS, PUT, DELETE, TRACE, CONNECT
- Host头 - 支持一个物理机部署多个站点。
- 新的缓存机制 - Cache-control,etag
- 断点续传 - content-range, 隐含了分而治之的思想。
- 分块传输 - transfer-encoding: chunk, 隐含了分而治之的思想。
Http/1.1的问题
- 线头阻塞(Head of line blocking)- HOLB
Http2 - 初入职场
2015年,Http2发布。 Http2与Http/1.1的不同是, Http2在应用层面解决了线头阻塞的问题. 为了解决这个问题,等待了15年.
Http2它有什么能力?
- 多路复用
- 用一个连接进行数据的收发。看到这里有些朋友是不是眼熟?Node和Redis都是用一个线程来专门做特定的事情。 创建一个连接,或者创建一个线程都是有开销的,既然如此,就用最少的连接或者线程好了。
- 一个场景:如果在一个连接上,同时想获取js, css, html文件应该怎么办? 以前的做法是获取完了js文件,然后再获得css文件。一个很自然的想法是将这文件切割和剁碎。然后拿到碎片之后再进行组装,从使用的角度来看,就是并发.
- 流和帧
- 一个流可以理解为一个请求
- 流可以设置优先级
- 流由多个帧组成。 每个帧是标记自己属于哪个流。 就好像每个人知道自己属于哪个组织.
- 帧是基于二进制编码的。
- 在传输过程中,帧和帧是乱序的。
- 基于二进制
- 头部压缩
- 基于HPACK算法
- 在客户端和服务端两端维护各自的字典
- 服务器推送
Http2是否真的完美无缺? 当然不是。 Http2只是部分的解决来队头阻塞的问题. 为什么呢?
因为TCP本质上是要保证顺序的,一个发送的包丢了之后,是无法收到后续发送包的响应的。 所以根据木桶原理,即使上层再怎么拆,怎么分,再怎么捣腾也没有.
一场风暴正在酝酿着.
Http/3 - 职场老油条
既然TCP是队头阻塞的元凶,那么把TCP干了不就可以了?这不可以,因为大多数互联网的设施是基于TCP, 简单的说就是TCP历史包袱较重. 当然了,也不可以对TCP直接修改,这些修改都牵涉到操作系统内核的更新。所以再TCP身上动念头的思路可以停止了.
换一个思路,可不可以从UDP身上下手?让UDP发100个包,它不会多发也不会少发,但它要是包丢了,它也不管. UDP身上的行为比较简单,可以基于 UDP做些事情.
于是, QUIC登场了。 QUIC的初衷是在UDP的基础上,实现和TCP类似的功能,而且要消除TCP的缺点。所以QUIC的整体战略定位还是蛮高的.
QUIC协议支持:
- 建立连接的优化
- 拥塞控制的优化
- 更好的多路复用
- 前向纠错特性
- 连接迁移
这个五个特性的最终目标都是为了一个字:快.
那么Http/3是什么? Http/3是HTTP/2 over QUIC.在2018年10月28日的邮件列表讨论中,互联网工程任务组(IETF) HTTP和QUIC工作组主席Mark Nottingham提出了将HTTP-over-QUIC更名为HTTP/3的正式请求,以“明确地将其标识为HTTP语义的另一个绑定……使人们理解它与QUIC的不同”,并在最终确定并发布草案后,将QUIC工作组继承到HTTP工作组。在随后的几天讨论中,Mark Nottingham的提议得到了IETF成员的接受,他们在2018年11月给出了官方批准,认可HTTP-over-QUIC成为HTTP/3