HTTP学习四:SPDY和HTTP/2.0
1 HTTP1.0/1.1与HTTPS的不足
1.1 HTTP1.0/1.1不足
- 单路连接
HTTP 协议的最大弊端就是每个 TCP 连接只能对应一个 HTTP 请求,即每个 HTTP 连接只请求一个资源,浏览器只能通过建立多个连接来解决。此外在 HTTP 中对请求是严格的先入先出(FIFO)进行的,如果中间某个请求处理时间较长会阻塞后面的请求
- 只允许由客户端主动发起请求
服务端只能等待客户端发送一个请求,在可以满足预加载的现状是一种桎梏
- HTTP头冗余
HTTP 头在同一个会话里是反复发送的,中间的冗余信息,比如 User-Agent、Host 等不需要重复发送的信息也在反复发送,浪费带宽和资源
- 明文传输
HTTP1.0/1.1在数据传输中使用的是明文,攻击者很容易获取数据内容
1.2 HTTPS不足
有一定的费用
性能问题
除了安全以外,不能解决HTTP1.0/1.1其他的问题
2 SPDY
SPDY是Google公司2012年发布的基于TCP/IP的应用层协议。SPDY协议通过压缩、多路复用和优先级来缩短网页的加载时间和安全性。
SPDY是Speedy的音,是更快的意思。
2.1 与HTTP的关系
SPDY 协议只是在性能上对 HTTP 做了很大的优化,其核心思想是尽量减少连接个数,而对于 HTTP 的语义并没有做太大的修改。具体来说是,SPDY 使用了 HTTP 的方法和页眉,但是删除了一些头并重写了 HTTP 中管理连接和数据转移格式的部分,所以基本上是兼容 HTTP 的。
Google 在 SPDY 白皮书里表示要向协议栈下面渗透并替换掉传输层协议(TCP),但是因为这样无论是部署起来还是实现起来暂时相当困难,因此 Google 准备先对应用层协议 HTTP 进行改进,先在 SSL 之上增加一个会话层来实现 SPDY 协议,而 HTTP 的 GET 和 POST 消息格式保持不变,即现有的所有服务端应用均不用做任何修改。
不管是普通用户还是开发者都可以像使用HTTP一样使用SPDY。
2.2 原理与特点
2.2.1 简单原理
2.2.1.1 协议层次
如上图SPDY位于HTTP之下,TCP和SSL之上
2.2.1.2 数据格式
SPDY把一次单向传输(服务器到客户端或客户端到服务器)的内容称作帧(frame),按协议组装帧内容称为装帧(framing)。
帧内容分为头部(header)和载荷(payload),类似于HTTP的头部(header)和实体(entity),但有以下区别:
- SPDY的头部都是8个字节,根据其中一些位的数值不同来表示不同的信息,并把HTTP的头部放到SPDY的载荷里。
- HTTP的实体(除POST信息外)是文件数据(data),SPDY的载荷除了可以是文件数据还可以是其它信息。
根据载荷的内容,帧分为控制帧和数据帧。
- 控制帧的数据格式:
+----------------------------------+
|C| Version(15bits) | Type(16bits) |
+----------------------------------+
| Flags (8) | Length (24 bits) |
+----------------------------------+
| Data |
+----------------------------------+
- 数据帧的数据格式:
+----------------------------------+
|C| Stream-ID (31bits) |
+----------------------------------+
| Flags (8) | Length (24 bits) |
+----------------------------------+
| Data |
+----------------------------------+
各数据位的意义:
C是第一个bit,值为0或1分别表示数据帧和控制帧。
Version为SPDY协议版本号,目前为3。
Type用作区分控制帧的类型。
Flags标记一些操作指示,不同的Type有不同的Flag。常见的是FLAG_FIN表示一个Stream结束。
Length表示Data的数据长度。
Data也就是payload。数据帧的Data就是一个文件(HTML文档、图片、脚本等),控制帧的Data根据Type不同而有不同。
Stream-ID记录流水号。
SPDY把一次HTTP Request/Response来回称作流(Stream),因为复用TCP连接,所以一个SPDY连接里会有多个流。为了区分不同的流,用Stream-ID来标记流水号(注:因为可以reload,所以不能以URL来确定一个流)。Stream-ID还存在于4种控制帧(SYN_STREAM、SYN_REPLY、RST_STREAM、HEADERS)的payload里。
控制帧的8种类型及作用:
- SYN_STREAM:创建流,在payload里携带请求(Request)。
- SYN_REPLY:回复创建流,在payload里携带HTTP头部。注意:SPDY把HTTP response拆开,response header放在控制帧SYN_REPLY的payload里并经过压缩,response entity放在数据帧里。
- RST_STREAM:报告流错误,payload里携带错误类型。
- SETTINGS:查询或设置控制信息。可处理的信息有8种:上传带宽、下载带宽、Round Trip时间、最大并行流数量、TCP的CWND值、下载重传率、初始窗口(Window)值、证书数量。
- PING:一种机制来测量Round Trip时间。
- GOAWAY:通知即将断开TCP连接。
- HEADERS:可做补充SVN_REPLY中的response header,或传递私有信息,特定的应用可用做自定义的扩展。
- WINDOW_UPDATE:设置窗口大小。
2.2.2 核心特性
单连接多路复用
在同一个域名下,SPDY只使用一个连接来加载一个页面的所有资源,在这个连接中可以打开多个流来同时传输数据
全双工,支持服务器推送技术
SPDY的流是双向的,允许服务器主动的同客户端建立流。SPDY通过Server Push和Server Hint技术,主动的向客户端推送资源,同时不发送已经缓存的资源
SPDY压缩了HTTP头
HTTP协议只能对HTTP BODY进行压缩,而现在很多网站cookie有很大的数据量,使得HTTP的请求数据越来越大。SPDY通过zlib对HTTP头进行了压缩,并强制开启HTTP BODY的Gzip压缩
请求分级,重要的资源优先传送
SPDY通过建立0~7的优先级,使服务器会优先处理优先级高的请求
强制使用 SSL传输协议
SPDY为了安全强制使用安全协议,通过压缩和优先级策略来弥补安全协议的性能问题
2.3 存在问题
多域名请求下同样要建立多条连接
SSL/TLS协议的性能问题
所有头部名都需要小写
客户端必须支持 gzip 压缩
Google已经不再支持SPDY
2.4 实施SPDY
国内使用SPDY的大厂是阿里,还开源了一款基于Nginx的服务器Tengine。
2.4.1 下载
wget http://tengine.taobao.org/download/tengine-2.1.2.tar.gz
2.4.2 解压
2.4.3 安装
- ./configure --prefix=/data/tengine --with-http_spdy_module --with-http_v2_module
- make
- make install
2.4.4 配置
先生成ssl证书,略过
server {
listen 443 ssl spdy;
server_name localhost;
ssl_certificate key/server.crt;
ssl_certificate_key key/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
2.4.5 启动
./nginx
2.4.6 验证
最新的chrome中已经不支持SPDY了,因此在firefox中进行验证。
3 HTTP/2.0
3.1 HTTP2.0介绍
HTTP 2.0即超文本传输协议 2.0,是下一代HTTP协议。是由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。是自1999年http1.1发布后的首个更新。HTTP 2.0在2013年8月进行首次合作共事性测试。
在开放互联网上HTTP 2.0将只用于https://网址,而 http://网址将继续使用HTTP/1,目的是在开放互联网上增加使用加密技术,以提供强有力的保护去遏制主动攻击。护自行发行证书。
3.2 HTTP2.0原理
3.2.1 历史
HTTP2.0是SPDY的升级,它采用了SPDY很多的特性和技术,但和SPDY有明显的区别:
- HTTP2.0支持明文传输,SPDY强制使用SSL/TLS
- HTTP2.0采用HPACK算法压缩消息头
- HTTP2.0对数据报文重新定义了二进制格式
3.2.1.1 HTTP2.0的二进制协议
如上图,HTTP1.x通过文本形式定义了起始行、报文头和实体,而HTTP2.0通过二进制格式定义了Length、Type、Flags、Stream ID、Payload
Length
整个二进制frame的长度
Type
Type定义了frame的类型,共10种
Flags
用bit位定义了一些重要的参数
Stream ID
用于控制流
Payload
Request的正文
HTTP2.0将HTTP1.0的起始行和报文头封装为Headers Frame,把实体封装为Data Frame
3.2.1.2 通信过程
如上图,客户端和服务端建立了一条TCP连接,每个stream都有一个ID,相同的ID表示是同一个资源。
建立连接阶段
客户端同服务端建立一条TCP连接,如果使用SSL/TLS,将建立一条加密的连接
请求数据阶段
客户端向服务端请求数据,发送一个frame,同一域名下的请求都会通过该连接发送到服务端
响应数据阶段
服务端向客户端响应数据,如果发现有其他的数据请求,通过同一TCP连接主动向客户端推送资源
3.3 新特性
多路复用
同SPDY一样,HTTP2.0支持多路复用,能在单一TCP连接中进行数据的传输
header压缩
同SPDY一样,为了减少报文头的数据量,HTTP2.0也支持header的压缩。但为了防止BREACH4和CRIME攻击,采用HPACK6对头部进行压缩
服务端推送
HTTP2.0同样提供了服务器推送技术
优先级和依赖关系
每个流都有自己的优先级别,会表明哪个流是最重要的,客户端会指定哪个流是最重要的,有一些依赖参数,这样一个流可以依赖另外一个流
重置
HTTP2.0引入了一个 RST_STREAM frame 来让客户端在已有的连接中发送重置请求,从而中断或者放弃响应。当浏览器进行页面跳转或者用户取消下载时,它可以防止建立新连接,避免浪费所有带宽。
流量控制
HTTP2.0每个独立流都有流控制,但只有DATA Frame才受控制。接收端通知发送方还能接收多少数据来控制。
3.4 实践HTTP2.0
同样通过Tengine来部署HTTP2.0,下载和安装见SPDY的实践。
3.4.1 配置
server {
listen 443 ssl http2 fastopen=3;
server_name localhost;
ssl_certificate key/server.crt;
ssl_certificate_key key/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
3.4.2 启动
./nginx -s reload
3.4.3 验证
在此过程中,要注意chrome浏览器的版本,如果大于51,则需要服务器使用openssl的alpn
下载openssl-1.0.2 然后重新编译时加入 --with-openssl=path
4 实用情况
移动端
最新版本移动端(IOS和Android)都支持SPDY和HTTP2.0,但较低版本的不支持HTTP2.0,但可以使用SPDY进行过渡
网页应用
最新的Chrome已经不支持SPDY
多域名
对大型网站和静态资源(图片、JS/CSS文件等等)分离的网站,可能不只一个域名,这时也会建立多个连接
5 参考
http://blog.csdn.net/hursing/article/details/22785475/
http://www.williamlong.info/archives/3119.html
http://mt.sohu.com/20160824/n465635124.shtml
http://mrpeak.cn/blog/http2/
http://www.jdon.com/dl/http2.html
HTTP学习四:SPDY和HTTP/2.0的更多相关文章
- TweenMax动画库学习(四)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- 《Java开发学习大纲文档》V7.0
<Java开发学习大纲文档>V7.0简介: 本文档是根据企业开发所需要掌握的知识点大纲进行总结汇编,是Java开发工程师必备知识体系,系统化学习针对性非常强,逻辑分析能力非常清晰;技术方面 ...
- Servlet学习:(三)Servlet3.0 上传文件
转: Servlet学习:(三)Servlet3.0 上传文件 2018年08月03日 11:57:58 iDark_CSDN 阅读数:362 一.注意事项 客户端(浏览器) 表单的提交方法必须是 ...
- Android JNI学习(四)——JNI的常用方法的中文API
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- 【Android】完善Android学习(三:API 3.0)
备注:之前Android入门学习的书籍使用的是杨丰盛的<Android应用开发揭秘>,这本书是基于Android 2.2API的,目前Android已经到4.4了,更新了很多的API,也增 ...
- SCARA——OpenGL入门学习四(颜色)
OpenGL入门学习[四] 本次学习的是颜色的选择.终于要走出黑白的世界了~~ OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. 无论哪种颜色模式,计算机都必须为每一个像素保存一些数 ...
- ZigBee学习四 无线+UART通信
ZigBee学习四 无线+UART通信 1) 协调器编程 修改coordinator.c文件 byte GenericApp_TransID; // This is the unique messag ...
- (转)SpringMVC学习(四)——Spring、MyBatis和SpringMVC的整合
http://blog.csdn.net/yerenyuan_pku/article/details/72231763 之前我整合了Spring和MyBatis这两个框架,不会的可以看我的文章MyBa ...
- Spring Boot 项目学习 (四) Spring Boot整合Swagger2自动生成API文档
0 引言 在做服务端开发的时候,难免会涉及到API 接口文档的编写,可以经历过手写API 文档的过程,就会发现,一个自动生成API文档可以提高多少的效率. 以下列举几个手写API 文档的痛点: 文档需 ...
随机推荐
- loadrunner监控linux服务器
参考http://www.cnblogs.com/yangxia-test/archive/2012/11/27/2790771.html http://www.cnblogs.com/candle8 ...
- testlink简单部署
CentOS+LAMP+testlink 环境 系统 CentOS6.5 软件 testlink-1.9.14 IP 192.168.0.158 部署 LAMP环境搭建 remi配置 wget htt ...
- catalina.properties
追踪 startup.bat set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat" call "%EXECUTABLE%&q ...
- bash和Bourne_shell的区别
Linux 中的 shell 有很多类型,其中最常用的几种是: Bourne shell (sh).C shell (csh) 和 Korn shell (ksh), 各有优缺点.Bourne she ...
- 在docker里部署网络服务
之前试着玩玩docker有一阵子了,今天算是头一回正式在docker里部署网络服务. 本来想和lxc差不多的东西那自然是手到擒来,没想到还是改了很多. 第一个遇到的问题是,远程连到docker宿主机干 ...
- kernel 内核安装
1.kernel 下载 https://cdn.kernel.org/pub/linux/kernel/ 2.解压源码 tar -zxvf linux-*.tar.gz 3.进入目录 cd linux ...
- Docker Machine v1.11.2安装与使用
官方文档:Docker Machine 官方文档:Docker Toolbox boot2docker安装包官网下载链接:Docker Toolbox-1.11.1b.exe 此安装包包含的“boot ...
- 海量用户-高并发SAAS产品测试上线流程
海量用户高并发SAAS产品测试上线流程 SAAS产品测试上线流程-以Web插件产品为例子 1 概述 在互联网产品中,IT公司之间更加注重产品功能之间的协作,SAAS形态的产品扮演着越来越重要的作用 ...
- C#可扩展编程之MEF学习笔记(三):导出类的方法和属性
前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经提供 ...
- jQuery实现返回顶部
由于项目需要,写了个返回顶部的小功能... /*返回顶部*/ function toTop() { $(".to_top").hide(); $(window).scroll(fu ...