HTTP1.0/1.1/2.0特性对比_转
转自:HTTP1.0 HTTP1.1 HTTP2.0 主要特性对比 https://segmentfault.com/a/1190000013028798
HTTP1.0
早先1.0
的HTTP
版本,是一种无状态、无连接的应用层协议。
HTTP1.0
规定浏览器和服务器保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP
连接,服务器处理完成后立即断开TCP
连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态)。
这种无状态性可以借助cookie/session
机制来做身份认证和状态记录。而下面两个问题就比较麻烦了。
首先,无连接的特性导致最大的性能缺陷就是无法复用连接。每次发送请求的时候,都需要进行一次TCP
的连接,而TCP
的连接释放过程又是比较费事的。这种无连接的特性会使得网络的利用率非常低。
其次就是队头阻塞(head of line blocking
)。由于HTTP1.0
规定下一个请求必须在前一个请求响应到达之前才能发送。假设前一个请求响应一直不到达,那么下一个请求就不发送,同样的后面的请求也给阻塞了。
为了解决这些问题,HTTP1.1
出现了。
HTTP1.1
对于HTTP1.1
,不仅继承了HTTP1.0
简单的特点,还克服了诸多HTTP1.0
性能上的问题。
首先是长连接,HTTP1.1
增加了一个Connection
字段,通过设置Keep-Alive
可以保持HTTP
连接不断开,避免了每次客户端与服务器请求都要重复建立释放建立TCP
连接,提高了网络的利用率。如果客户端想关闭HTTP
连接,可以在请求头中携带Connection: false
来告知服务器关闭请求。
其次,是HTTP1.1
支持请求管道化(pipelining
)。基于HTTP1.1
的长连接,使得请求管线化成为可能。管线化使得请求能够“并行”传输。举个例子来说,假如响应的主体是一个html
页面,页面中包含了很多img
,这个时候keep-alive
就起了很大的作用,能够进行“并行”发送多个请求。(注意这里的“并行”并不是真正意义上的并行传输,具体解释如下。)
需要注意的是,服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容。
也就是说,HTTP
管道化可以让我们把先进先出队列从客户端(请求队列)迁移到服务端(响应队列)。
如图所示,客户端同时发了两个请求分别来获取html
和css
,假如说服务器的css
资源先准备就绪,服务器也会先发送html
再发送css
。
换句话来说,只有等到html
响应的资源完全传输完毕后,css
响应的资源才能开始传输。也就是说,不允许同时存在两个并行的响应。
可见,HTTP1.1
还是无法解决队头阻塞(head of line blocking
)的问题。同时“管道化”技术存在各种各样的问题,所以很多浏览器要么根本不支持它,要么就直接默认关闭,并且开启的条件很苛刻...而且实际上好像并没有什么用处。
那我们在谷歌控制台看到的并行请求又是怎么一回事呢?
如图所示,绿色部分代表请求发起到服务器响应的一个等待时间,而蓝色部分表示资源的下载时间。按照理论来说,HTTP响应理应当是前一个响应的资源下载完了,下一个响应的资源才能开始下载。而这里却出现了响应资源下载并行的情况。这又是为什么呢?
其实,虽然HTTP1.1
支持管道化,但是服务器也必须进行逐个响应的送回,这个是很大的一个缺陷。实际上,现阶段的浏览器厂商采取了另外一种做法,它允许我们打开多个TCP的会话。也就是说,上图我们看到的并行,其实是不同的TCP连接上的HTTP
请求和响应。这也就是我们所熟悉的浏览器对同域下并行加载6~8个资源的限制。而这,才是真正的并行!
此外,HTTP1.1
还加入了缓存处理(强缓存和协商缓存[传送门])新的字段如cache-control
,支持断点传输,以及增加了Host字段(使得一个服务器能够用来创建多个Web站点)。
HTTP2.0
HTTP2.0
的新特性大致如下:
二进制分帧
HTTP2.0
通过在应用层和传输层之间增加一个二进制分帧层,突破了HTTP1.1
的性能限制、改进传输性能。
可见,虽然HTTP2.0
的协议和HTTP1.x
协议之间的规范完全不同了,但是实际上HTTP2.0
并没有改变HTTP1.x
的语义。
简单来说,HTTP2.0
只是把原来HTTP1.x
的header
和body
部分用frame
重新封装了一层而已。
多路复用(连接共享)
下面是几个概念:
- 流(
stream
):已建立连接上的双向字节流。 - 消息:与逻辑消息对应的完整的一系列数据帧。
- 帧(
frame
):HTTP2.0
通信的最小单位,每个帧包含帧头部,至少也会标识出当前帧所属的流(stream id
)。
从图中可见,所有的HTTP2.0
通信都在一个TCP
连接上完成,这个连接可以承载任意数量的双向数据流。
每个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(stream id
)重新组装。
举个例子,每个请求是一个数据流,数据流以消息的方式发送,而消息又分为多个帧,帧头部记录着stream id
用来标识所属的数据流,不同属的帧可以在连接中随机混杂在一起。接收方可以根据stream id
将帧再归属到各自不同的请求当中去。
另外,多路复用(连接共享)可能会导致关键请求被阻塞。HTTP2.0
里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回给客户端,数据流还可以依赖其他的子数据流。
可见,HTTP2.0
实现了真正的并行传输,它能够在一个TCP
上进行任意数量HTTP
请求。而这个强大的功能则是基于“二进制分帧”的特性。
头部压缩
在HTTP1.x
中,头部元数据都是以纯文本的形式发送的,通常会给每个请求增加500~800字节的负荷。
比如说cookie
,默认情况下,浏览器会在每次请求的时候,把cookie
附在header
上面发送给服务器。(由于cookie
比较大且每次都重复发送,一般不存储信息,只是用来做状态记录和身份认证)
HTTP2.0
使用encoder
来减少需要传输的header
大小,通讯双方各自cache
一份header fields
表,既避免了重复header
的传输,又减小了需要传输的大小。高效的压缩算法可以很大的压缩header
,减少发送包的数量从而降低延迟。
服务器推送
服务器除了对最初请求的响应外,服务器还可以额外的向客户端推送资源,而无需客户端明确的请求。
HTTP1.1的合并请求是否适用于HTTP2.0
首先,答案是“没有必要”。之所以没有必要,是因为这跟HTTP2.0
的头部压缩有很大的关系。
在头部压缩技术中,客户端和服务器均会维护两份相同的静态字典和动态字典。
在静态字典中,包含了常见的头部名称以及头部名称与值的组合。静态字典在首次请求时就可以使用。那么现在头部的字段就可以被简写成静态字典中相应字段对应的index
。
而动态字典跟连接的上下文相关,每个HTTP/2
连接维护的动态字典是不尽相同的。动态字典可以在连接中不听的进行更新。
也就是说,原本完整的HTTP报文头部的键值对或字段,由于字典的存在,现在可以转换成索引index
,在相应的端再进行查找还原,也就起到了压缩的作用。
所以,同一个连接上产生的请求和响应越多,动态字典累积得越全,头部压缩的效果也就越好,所以针对HTTP/2
网站,最佳实践是不要合并资源。
另外,HTTP2.0
多路复用使得请求可以并行传输,而HTTP1.1
合并请求的一个原因也是为了防止过多的HTTP
请求带来的阻塞问题。而现在HTTP2.0
已经能够并行传输了,所以合并请求也就没有必要了。
总结
HTTP1.0
- 无状态、无连接
HTTP1.1
- 持久连接
- 请求管道化
- 增加缓存处理(新的字段如
cache-control
) - 增加
Host
字段、支持断点传输等
HTTP2.0
- 二进制分帧
- 多路复用(或连接共享)
- 头部压缩
- 服务器推送
参考:
https://www.zhihu.com/questio...
https://segmentfault.com/q/10...
http://imweb.io/topic/554c587...
http://web.jobbole.com/85635/
HTTP1.0/1.1/2.0特性对比_转的更多相关文章
- C# HTTP1.0 1.1 2.0与HTTPS 、TCP/IP协议的UDP与TCP、 Socket介绍与WebSocket
一.HTTP1.0 1.1 2.0和HTTPS 1.HTTP协议是什么? HTTP协议是超文本传输协议的缩写,英文是Hyper Text Transfer Protocol.它是从WEB服务器传输超文 ...
- HTTP1.0,1.1,2.0,HTTPS
HTTP1.0/1.1/2.0/HTTPS HTTP(超文本传输协议)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准.设计HTTP最初的目的是为了提供一种发布和接收HTML页 ...
- (数据科学学习手札129)geopandas 0.10版本重要新特性一览
本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 就在前不久,我们非常熟悉的Python地理 ...
- Jdk5.0中出现的新特性
掌握jdk5.0中出现的新特性1.泛型(Generics)2.增强的"for"循环(Enhanced For loop)3.自动装箱/自动拆箱(Autoboxing/unboxin ...
- QT5.1.0,QT4.8.0以及VC2010、VC2012的测试对比
QT5.1.0,QT4.8.0以及VC2010.VC2012的交叉测试对比. 测试1: 用VC2012静态编译了QT5.1.0. 编译速度很慢,生成完成后,用VC2012+QT5.1.0进行程序生成, ...
- C#6.0 中的那些新特性
C#6.0 中的那些新特性 前言 VS2015在自己机器上确实是装好了,费了老劲了,想来体验一下跨平台的快感,结果被微软狠狠的来了一棒子了,装好了还是没什么用,应该还需要装Xarmain插件,配置一些 ...
- Android 5.0(棒棒糖))十大新特性
Android 5.0(棒棒糖))十大新特性 1. 全新Material Design设计风格 Android Lollipop全新的设计语言是受到了多种因素影响,是一种大胆的平面化创新.换句话说,谷 ...
- Android 7.0(牛轧糖)新特性
Android 7.0(牛轧糖)新特性 谷歌正式在I/O大会现场详细介绍了有关Android 7.0的大量信息.目前,我们已经知道,新一代Android操作系统将支持无缝升级,能够通过Vulkan A ...
- C#6.0,C#7.0新特性
C#6.0新特性 Auto-Property enhancements(自动属性增强) Read-only auto-properties (真正的只读属性) Auto-Property Initia ...
随机推荐
- linux 查看 cpu个数 核心数 线程数
深蓝的blog:http://blog.csdn.net/huangyanlong/article/details/43935535 (1).查看cpu信息 [root@xckydb ~]# cat ...
- Python 爬虫 解决escape问题
爬取某个国外的网址,遇到的编码问题 ,在前段页面 返回的数据是 亞洲私人珍藏賣,令仝好分享他為此 所傾注的心血與熱愛。 爬虫源码是: url = 'http://www.bonhams.com/auc ...
- Ubuntu下设置开机后自动运行命令(转)
从道理上来讲,Ubuntu开机应该是能够设置执行一些脚本的,事实上确实如此,网上给出了很多解决的方案,基本上是分为两种, 第一种是编辑/etc/下的rc.local脚本, 然后把对应的需要执行的脚本写 ...
- 下载必要的android sdk
做android自动化测试,必须要下载anroid sdk 下载后最少安装方法:
- unity, shader, Tags的位置
Tags写在Pass里,是不对的,比如: 结果一看shader的Inspector面板,Render queue的值居然不是3001,而是2000: 改为: 再看shader的inspector面板, ...
- Chrome浏览器查看 iframe信息 OpenFrame
https://chrome.google.com/webstore/search/openframe?hl=zh-CN&_category=extensions 搜索 OpenFrame 添 ...
- Machine Learning Books Suggested by Michael I. Jordan from Berkeley
http://www.statsblogs.com/2014/12/30/machine-learning-books-suggested-by-michael-i-jordan-from-berke ...
- iOS开发如何学习前端(1)
iOS开发如何学习前端(1) 我为何学前端?因为无聊. 概念 前端大概三大块. HTML CSS JavaScript 基本上每个概念在iOS中都有对应的.HTML请想象成只能拉Autolayout或 ...
- cxf、struts、spring中web.xml过滤url问题解决方案
利用struts2自带的正则匹配,应该说这算是最官方的解决方案了 在struts.properties中加正则匹配 struts.action.excludePattern=/webservice/. ...
- Python+SparkStreaming+kafka+写入本地文件案例(可执行)
从kafka中读取指定的topic,根据中间内容的不同,写入不同的文件中. 文件按照日期区分. #!/usr/bin/env python # -*- coding: utf-8 -*- # @Tim ...