一文领略 HTTP 的前世今生(下)

简介: 一文领略 HTTP 的前世今生(下)

这时候 Google 看不下去了,你不搞是吧?我自己搞我的,我自己和我自己玩,我用户群体大,我有 Chrome,我服务多了去了。


Google 推出了 SPDY 协议,凭借着它全球的占有率超过了 60% 的底气,2012年7月,开发 SPDY 的小组公开表示,它正在努力实现标准化。


HTTP 坐不住了,之后互联网标准化组织以 SPDY 为基础开始制定新版本的 HTTP 协议,最终在 2015 年发布了 HTTP/2。

HTTP/2 版本主要增加以下几点:

  • 是二进制协议,不再是纯文本。
  • 支持一个 TCP 连接发起多请求,移除了 pipeline。
  • 利用 HPACK 压缩头部,减少数据传输量。
  • 允许服务端主动推送数据。

从文本到二进制其实简化了整齐的复杂性,解析数据的开销更小,数据更加紧凑,减少了网络的延迟,提升了整体的吞吐量。


image.png


支持一个 TCP 连接发起多请求,即支持多路复用,像 HTTP/1.1 pipeline 还是有阻塞的情况,需要等前面的一个响应返回了后面的才能返回


而多路复用就是完全异步化,这减少了整体的往返时间(RTT),解决了 HTTP 队头阻塞问题,也规避了 TCP 慢启动带来的影响


HPACK 压缩头部,采用了静态表、动态表和哈夫曼编码,在客户端和服务器都维护请求头的列表,所以只需要增量和压缩过的头部信息,服务端拿到之后组装一下就能得到完整的头部信息。


形象一点就是如下图所示:


image.png


服务端主动推送数据,这个其实就是减少了请求的次数,比如客户端请求 1.html,我把 1.html 需要的 js 和 css 也一块送过去,省的之后客户端再请求我要 js ,我要这个 css。

可以看到 HTTP/2 的整体演进都是往性能优化的角度发展,因为此时的性能就是痛点,任何东西的演进都是哪里痛医哪里。


当然有一些例外,比如一些意外,或者就是“闲的蛋疼”的那种捯饬。

这次推进属于用户揭竿而起为之,你再不给我升级我自己搞了,我有着资本,你自己掂量。


最终结果是好的,Google 后来放弃了 SPDY ,拥抱标准,而 HTTP/1.1 这个历史包袱太重了,所以 HTTP/2 到现在也只有大致一半的网站使用它。


image.png


HTTP 3 时代



这 HTTP/2 还没捂热, HTTP/3 怎么就来了?

这次又是 Google,它自己突破自己,主要也是源自于痛点,这次的痛点来自于 HTTP 依赖的 TCP。


TCP 是面向可靠的、有序的传输协议,因此会有失败重传和按序机制,而 HTTP/2 是所有流共享一个 TCP 连接,所以会有 TCP 层面的队头阻塞,当发生重传时会影响多个请求响应。


并且 TCP 是基于四元组(源IP,源端口,目标IP,目标端口)来确定连接的,而在移动网络的情况下 IP 地址会频繁的换,这会导致反复的建连。


还有 TCP 与 TLS 的叠加握手,增加了延时。


问题就出在 TCP 身上,所以 Google 就把目光瞄向了 UDP。


UDP 我们知道是无连接的,不管什么顺序,也不管你什么丢包,而 TCP 我在之前的文章说的很清楚了TCP疑难杂症解析不了解的同学可以去看看。


简单的说就是 TCP 太无私了,或者说太保守了,现在需要一种更激进的做法。

那怎么搞? TCP 改不动我就换!然后把 TCP 可靠、有序的功能提到应用层来实现,因此 Google 就研究出了 QUIC 协议。


image.png

image.png

注意上图是在已经和服务端握过手之后的,由于网络切换等原因才有 0 RTT ,也就是 Connection ID 在之前生成过了

如果是第一次建连还是需要多次握手的,我们来看一下简化的握手对比图。


image.png


所以所谓的 0RTT 是在之前已经建连的情况下。

当然还有 HTTP/2 提到的 HPACK,这个是依赖 TCP 的可靠、有序传输的,于是 QUIC 得搞了个 QPACK,也采用了静态表、动态表和哈夫曼编码。


它丰富了 HTTP/2 的静态表,从 61 项加到了 98 项

上面提到的动态表,是用来存储未包含在静态表中的头部项,假设动态表还未收到,后面来解头部的时候肯定要被阻塞的。


所以 QPACK 就另开一条路,在单向的 Stream 里传输动态表的编解码,单向传输好了,接受端到才能开始解码,也就是说还没好你就先别管,防止做一半卡住了


那还有前面提到的 TCP 队头阻塞, QUIC 是怎么解决的呢?毕竟它也要保证有序和可靠啊。


因为 TCP 不认识每个流分别是哪个请求的,所以它只能全部阻塞住,而 QUIC 知道,因此比如请求 A 丢包了,我就把 A 卡住了就行,请求 B 完全可以全部放行,丝毫不受影响。


可以看到基于 UDP 的 QUIC 还是很强大的,而且人家用户多,在 2018 年,互联网标准化组织 IETF 提议将 HTTP over QUIC 更名为 HTTP/3 并获得批准


可以看到需求又推动技术的进步,由于 TCP 自身机制的限制,我们的目光已经往 UDP 上靠了,那 TCP 会不会成为历史呢?

我们拭目以待。


最后


今天我们大致过了一遍 HTTP 发展的历史和它的演进之路,可以看到技术是源于需求,需求推动着技术的发展。


本质上就是人的惰性,只有痛了才会成长


而且标准其实也是巨头们为了他们的利益推动的,不过标准确实能减轻对接的开销,统一而方便。


当然就 HTTP 来说还是有很多内容的,有很多细节,很多算法,比如拿 Connection ID 来说,不同的四元组你如何保证请求一定会转发到之前的服务器上?


所以今天我只是浅显的谈了谈大致的演进,具体的实现还是得靠各位自己摸索,或者之后有机会我再写一些。


不过相对于这些实现细节我更感兴趣的是历史的演进,这能让我从时代背景等一些约束来得知,为什么这东西一开始是这么设计的,从而更深刻的理解这玩意。

而且历史还是很有趣的,不是么?




相关文章
|
域名解析 缓存 安全
一文领略 HTTP 的前世今生(中)
一文领略 HTTP 的前世今生(中)
一文领略 HTTP 的前世今生(中)
|
存储 网络协议 程序员
一文领略 HTTP 的前世今生(上)
一文领略 HTTP 的前世今生(上)
一文领略 HTTP 的前世今生(上)
|
存储 Web App开发 监控
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
我们以前使用过的对hbase和hdfs进行健康检查,及剩余hdfs容量告警,简单易用 1.针对hadoop2的脚本: #/bin/bashbin=`dirname $0`bin=`cd $bin;pwd`STATE_OK=...
1053 0
|
Web App开发 新零售 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
1.尽可能地了解需求,系统层面适用开闭原则 2.模块化,低耦合,能快速响应变化,也可以避免一个子系统的问题波及整个大系统 3.
750 0
|
Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
异步通信 对于BS(Browser-Server 浏览器)架构,很多情景下server的处理时间较长。 如果浏览器发送请求后,保持跟server的连接,等待server响应,那么一方面会对用户的体验有负面影响; 另一方面,很有可能会由于超时,提示用户服务请求失败。
769 0
|
Web App开发 大数据
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
                                                                               1.
1694 0
|
Web App开发 前端开发 Java
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
服务端需在vm arguments一栏下加上    -agentlib:jdwp=transport=dt_socket,server=y,address=8000 并以run模式启动 如果以debug模式启动服务端...
722 0
|
Web App开发 前端开发 Linux
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
[root@hadoop058 ~]# mii-tool eth0: negotiated 100baseTx-FD, link ok 100M linux 下查看网卡工作速率 Ethtool是用于查询及设置网卡参数的命令。
647 0
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
生产服务器环境最小化安装后 Centos 6.5优化配置备忘 本文 centos 6.5 优化 的项有18处,列表如下: 1、centos6.
1544 0
|
Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
如何获取设备特征码、版本号、激活码?方式一 第一步:打开凯立德移动导航系统,进入地图界面,点击“查找”第二步:在查找页面以“快拼”的输入方式下,输入“AAAAAA”(6个A)
979 0

热门文章

最新文章