引言

对于 http 协议的认知一直都是零散的,研究了一下,于是有了这么个文章

本文一方面是介绍 http 的起源,另外一方面是关注 http 数据传输部分的技术演变并尝试去理解设计者的思路。因此,偏向于前端的功能特点会被忽略。

为什么要去了解历史进程呢?有句话叫:欲知其道,必先为史。任何一项技术必然有他的出发点,了解技术诞生的大环境,有助于更好的理解技术本身。也就是说去思考这样的问题:为什么要这样设计?有没有更好的方案?

版本号

http从0.9版本(1989年)到还未完全标准化的3.0(2018年),一共有0.9 / 1.0 / 1.1/ 2.0 / 3.0几个主要版本,下面将依次介绍。

协议萌芽

核心人物叫Tim Berners-Lee, 当时在CERN(欧洲核子研究中心)工作,CERN是一个“分布式”的研究机构,意思是研究人员分布在世界各地。所以学术交流是家常便饭,如果能有个东西能够远程分享文档那是再好不过了。

当时tcp/ip协议簇已经是主流,并且有很多基于tcp/ip协议的通信技术已经投入社会使用。因此,基于tcp协议的超文本共享便是顺理成章。

Tim构思了一个由很多节点组成的文档网络(proposal mesh),并且可以通过browser浏览这些hypertext。所谓hypertext就是不限定为普通文本,可以包含各种形式的内容(MIME)。本质上就能达成学术交流的诉求。后面Tim为了论证这个想法,自己开发了服务端以及浏览器。当这个应用被业界认可后,慢慢走向标准化,就是今天熟知的http协议。

协议诞生 - http/0.9 & http/1.0

http/0.9
这个版本上是Tim证明自己的想法而开发的原型版本,只有get方法,所谓的The One-Line Protocol,即 GET some_url。特点是:

  • response 是 html 文本
  • tcp 连接在 response 之后关闭

当然,Tim设想的http不止这些feature

http/1.0
http/0.9的问世,社会需求是认可的,但是功能还不满足一些场景应用。于是http/1.0主要是基于0.9增强了功能以适应场景需求,比如:

  • 内容协商 除了超文本,还支持其他格式
  • request-header / response-header
  • 代理
  • 缓存
  • connection 同样也是在一轮 request / response 之后关闭

这些内容都没什么特别的,因为处于我们当前视角(主流http/1.1版本)来看,反而是“减配”了

1990-1995是http/1.0的发展时段,这个领域开始风起云涌。比如网景浏览器的诞生也是在这个阶段。李彦宏工作过的infoseek也是1994年成立,两年后另外一个做搜索的项目开始启动了——google。

广泛应用 - http1.1

同样的,1.1也是基于1.0增强功能,以适应各种场景需求。关注两个点:

连接复用

  • 请求/响应默认不立即关闭,互相交换 Connection: Close之后才关闭
  • 建议每个client对一个server,最多持有2个连接rfc2616#section-8.1.4,实际上浏览器支持的是大于这个数的,浏览器的settings

被废弃的http pipeline
虽然这个技术点被废弃了,但是还是可以品味一下设计思路

HTTP 情况是,首先建立一个tcp连接,一个请求发给服务端,然后等待服务端响应,这样一个流程就完成了,这个tcp连接就承载这个轮回。这种阻塞式的交互导致有一定的“空档期”,即浪费了网络及计算资源。

为了高效利用连接,设计了一个叫http pipeline的机制:一个tcp连接可以同时支持多个请求,比如请求r1 r2 r3连续发给服务器,当服务器处理完成 响应R1 R2 R3(这里r代表request,R代表response),RFC里面描述了一句要求:

A server MUST send its responses to those requests in the
same order that the requests were received.
// 意思是服务器发送响应的时候得按照收到request的顺序。

为什么要有这个要求?
个人分析是因为当client收到一个response R,但是由于pipeline的原因,client无法确认这个 R是对应哪个request,因此约定一种先后顺序的队列机制。

有什么问题
由于这个机制的存在,反而约束了数据传输,并没有达到真正意义上的多路复用。比如服务端收到请求顺序如下:r1 - r2 - r3,假如r3在server内部最先处理完成,也只能等到r1 r2 处理完成并先行发送。这种情况可能会导致队头阻塞问题

改进思路
由于 client 无法给 response “对号入座”,因此可以在请求时加上一种 identifier 的机制。比如request(id: 678),服务器处理完成后,response(id: 678),这样 client 端就能对号入座了,同时也不用限定响应队列的先后关系,实际上 2.0 就是这么干的。

没有 pipeline 的情况下,为了提升资源loading效率,业界广泛利用一些 trick 来达到并行 load 资源的目的,比如 突破浏览器域名并发限制的解决方案、using-multiple-tcp-connections

成功的多路复用 - http2.0

这个版本目标在于提升 PLT(page load time),这个PLT实际上就两个点,一是资源传输,二是资源解析渲染。

  • 资源解析渲染主要在于前端的优化,比如:资源渲染逻辑、语法、优先渲染可视组件等等。
  • 相对于渲染而言,数据传输还是比较卡脖子的事情,因为各种应用总是越来越复杂。

因此,还是关注数据传输。

从1.1版本的 pipeline 技术可以看出,http 的设计在打算使用多路复用。虽然因为存在一些弊端,pipeline 被抛弃了,但是大体思路是没有问题的。

http/2 在数据传输这部分是成功的一次多路复用(multiplexing)

在发送端把数据(request/response)“打碎”成Frame,在同一个 tcp connection 中传输,再在接收端把Frame重组。通过这种方式实现一个 connection 上承载多个Frame,由于 tcp connection的 Frame 可能来自于不同的 request/response,这样就实现了一个连接承载多个请求/响应。

图里面有几个概念

  • Stream: 一个 connection 中有多个 stream,每个 stream 有唯一 ID。stream 是个逻辑上的通信通道。
  • Message: 相当于一个 request 或 response
  • Frame: 一个 Message 包含一个或多个 Frame,Frame 就是 http2 的最小传输单元


正如前面如说的,请求在发送端“打碎”成 Frame,带上 stream-id m,当服务端响应时,每个 Frame 的 stream-id 均为 m,这样浏览器就能够重组,从而实现多路复用。

流量控制
基于应用层对于流量控制的需求(比如网页视频播放暂停),http/2 定义了 Flow Control。这个功能是面向 connection 或者是 stream 级别的。

这个功能类似于 tcp 的滑动窗口机制,由接收端去通知接收窗口大小

http/2 总结
通过引入 Frame + Stream 机制成功实现多路复用,这样一来

  • 一个域名下只需要一个 tcp 连接
  • 连接少了自然 TLS 握手也少了
  • 多路复用提升了网络效率
  • 应用层可控的流量控制

当然 http/2 还有其他功能,本文侧重数据传输,因此略过

大刀阔斧改革 - http3.0(http over quic)

QUIC是google研发的协议,然后提交给IETF工作组,然后标准化作为http3版本的传输协议

从前面介绍传输机制的演变过程可以看到:

  • 1.0 及之前每次通信就建立一个 connetion,用完关闭
  • 1.1 版本一方面持久化 connection 来提升性能,另外一方面尝试了多路复用( pipeline ),但由于一些弊端被弃用
  • 2.0 版本通过引入 Frame + Stream 机制成功克服了 pipeline 的弊端并实现多路复用,可以实现一个连接并发传送多个资源文件

那么http3.0如何变化?

  • 可以看到2.0已经有 Frame、flow-control 等概念,等等!这不是 tcp 的工作吗,那一定还需要 tcp 吗?
  • 在1.1推行全网的加密传输。既然加密成了“标配”,https需要握手,tcp需要握手,为什么不合并在一起?

这样看来3.0的方向就清晰了,它主要的优化方向:

  1. tcp握手 & tls握手重复多余
  2. tcp仍有HOL问题,因为2.0虽然多路复用了,但是一个资源的失败会影响其他资源的传输。
  3. 基于tcp的协议栈即使有问题也不能难以优化,涉及到网络中间设备、操作系统等,牵一发动全身

下图就是QUIC协议的结构示意

http/3 引入了一个新的传输层:QUIC 协议,它是基于UDP的、面向连接的、可靠的、安全的(囊括加密套件)传输协议。

QUIC传输相关的特性

  • 类似 TCP 的 ACK 、流量控制、拥堵控制等特性
  • 类似 TLS 的加密套件
  • 因为 UDP 本身没有 connection 的概念,QUIC 需要类似 TCP 的 connection 概念
  • 舍弃了 ip/port 四元组的connection,用 connection id替换,用以解决NAT-rebind
  • 为了解决HOL问题,基于http2引入了多stream的概念。流量控制可以是connection级别的也可以是stream级别的。
  • 把传输控制这个部分从传输层上移到了应用层,在工程实践中进行后续的优化、扩展、部署变得比较方便

[待细化…]

结语

  • 每一次基础技术的革新,都可能催生新的应用、新的商业机会。http的诞生也同样也引发了创业浪潮。

  • http/1.1 是基本满足需求;http/2.0 是优化传输;http/3.0 是深度定制协议;

  • http/3.0 的 QUIC 协议实际上可以单独剥离使用,比如一些 C/S 场景

  • tcp 本身设计是面向长连接优化的(比如慢启动机制),持久化连接肯定是最优解

  • 网络应用一定是倾向于更复杂的,商家都倾向于为用户提供多样性的、动态的服务。很明显,这种服务需求必然需要 load 更多的资源,比如淘宝在各个节日页面都在发生响应的变化。
    现在一定层面上都是前端技术,前端技术的弊端在于 page loading。光速是一定的,但是如何去优化传输是很重要的板块。

ref

  1. home of the first website
  2. www project history
  3. short-history-web
  4. Evolution of HTTP
  5. 欧洲核子研究中心-wikipedia
  6. rfc1945 http/1.0
  7. Introduction to HTTP/2
  8. The QUIC Transport Protocol:
    Design and Internet-Scale Deployment
  9. rfc2616-sec4
  10. HTTP/1.1-Connections rfc2616-sec8
  11. rfc2068-19.7.1 Compatibility with HTTP/1.0 Persistent Connections
  12. Hypertext document retrieval system and method
  13. infoseek-wikipedia
  14. Robin_Li-wikipedia
  15. History of the Internet
  16. History of TCP/IP
  17. Browser connection limitations
  18. undertow Http2ClientConnection.java#L397
  19. How to capture a NetLog dump
  20. netlog-viewer
  21. 《HTTP/2 in Action》
  22. 突破浏览器域名并发限制的解决方案
  23. cloudflare - The Road to QUIC
  24. chromium-quic
  25. quicwg
  26. Network Address Translation Support for QUIC
  27. 腾讯罗成-QUIC协议原理分析
  28. 让互联网更快的协议,QUIC在腾讯的实践及性能优化
  29. nginx-quic
  30. Understanding network overhead

HTTP数据传输机制的演变:从0.9到3.0相关推荐

  1. 浅议gRPC的数据传输机制和回调机制

    本文来自DotNET技术圈 作者:溪源 一.引子 如您所知,gRPC是目前比较常见的rpc框架,可以方便的作为服务与服务之间的通信基础设施,为构建微服务体系提供非常强有力的支持. 而基于.NET Co ...

  2. GSM模块_GPRS数据传输机制和原理

    GSM模块_GPRS数据传输机制和原理 通信专业术语 GPRS网络结构 GPRS工作原理 GPRS协议模型 GPRS连接过程详解 GPRS的应用--TCPIPPPP GPRS相关AT指令集 GPRS网 ...

  3. android 6.0 log,android 6.0 logcat机制(三)logd处理请求log

    一.logd LogReader监听logdr socket 在logd的main函数中会有一个监听logdr socket的LogReader类 我们来看下main函数的源码 LogReader * ...

  4. 网络请求(一)— HTTP/0.9、HTTP/1.0、HTTP/2.0、SPDY

    1 TCP/IP概念 TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的协议簇 ...

  5. Aurora 8B/10B、PCIe 2.0、SRIO 2.0三种协议比较

    在高性能雷达信号处理机研制中,高速串行总线正逐步取代并行总线.业界广泛使用的Xilinx公司Virtex-6系列FPGA支持多种高速串行通信协议,本文针对其中较为常用的Aurora 8B/10B和PC ...

  6. WAP 2.0 VS WEB 2.0

    [声明]本文采自互联网,文章版权归原文作者所有,贴子以"现状"提供且没有任何担保也没有授予任何权利. WAP 2.0 不言而喻,移动商务需要传送无线数据,然而现有无线传送技术的效率 ...

  7. Djang1.8+Python2.0迁移到Django2.0+Python3.6注意事项(转)

    Djang1.8+Python2.0迁移到Django2.0+Python3.6注意事项 参考:https://blog.csdn.net/weixin_40475396/article/detail ...

  8. C#6.0,C#7.0新特性

    C#6.0,C#7.0新特性 C#6.0新特性 Auto-Property enhancements(自动属性增强) Read-only auto-properties (真正的只读属性) Auto- ...

  9. android 6.0 自定义application,Android6.0之App中的资源管理对象创建

    Android与资源管理相关的类Resouces和AssetManager很有必要清楚他们的创建过程. 与资源查找与加载操作相关的类 资源查找与加载主要是靠Android资源管理框架来完成的,而And ...

  10. 双十一购物节,Nacos 1.4.0 + Go SDK 1.0.1发布

    一年一度的双十一购物节又来了,不知道小伙伴们有没有抢到想要的商品呢? 无论您是否"剁手"成功,Nacos都为社区的各位奉上礼物庆祝双十一 – Nacos 1.4.0和nacos-s ...

最新文章

  1. canvas 文字颜色_Canvas技术概述
  2. linux 虚拟机扩展硬盘后扩展到分区
  3. 块语法Block在MVC思维的妙用之多重M层代理传值
  4. ActiveMQ点对点消息通信demo
  5. CONNECT_NODES 中的SET HANDLER
  6. python桌面开发吐血_想用java写个桌面小demo,就布局都差点写吐血了,学艺不精...
  7. 北邮 鲁鹏老师 视频笔记
  8. 最大表示法--环形字符串最大字典序(HDU 5442)
  9. 802.x无线认证服务器,无线802.1X认证
  10. 2行Python给图片加水印,太强了!
  11. 图像区块分割与采样YUV4:2:0
  12. 『Nginx』Nginx部署Https 443转发
  13. 《嵌入式 - Lwip开发指南》第3章 移植LWIP(无系统)
  14. 深入解析String intern
  15. RFID医疗耗材柜管理系统中的解决方案
  16. 计算机网络 :P2P文件分发
  17. CSS实现橡皮筋效果
  18. 机器视觉,工业相机镜头笔记
  19. 才上架不久的超级玛丽3号max要停售保70岁版本?这对我们消费者有什么影响,一文解析
  20. 编译器无法解析的外部符号问题

热门文章

  1. 物联网大数据商业模式画布-0406-v1.1王玉娟
  2. mysql绿化,Mysql精简与绿化版本
  3. 平衡车gazebo仿真
  4. 计算机丢失dll文件怎么弄,电脑缺少dll文件怎么办
  5. Linux中用两个网卡同时上内外网
  6. Ragel State Machine Compiler 的速度测试
  7. 综合管廊:道路工程综合管廊施工方案(图文)
  8. 推荐2021年最受欢迎的15款Vue后台管理模板
  9. Java IO流(超详细!)
  10. 51、AVR、PIC、MSP430、ARM五大单片机全解析