why?SPDY产生的原因
http 协议的以下问题,造成页面加载时间长:
1 一个tcp/ip 连接,只能传输一个请求。一个tcp/ip连接,将导致500ms的延迟
2 只有客户端能发送请求,服务器不能主动发送请求
3 请求和响应头都没有压缩。请求头的大小从200b到2KB不等,这些未压缩的数据将造成明显的延迟
4 重复的头。不变的数据如:ua、host、Accept*deng每次都发送
5 数据内容压缩时可选的,而不是强制的
google 实验表明,页面加载速度对于用户体验、页面经济转化率有非常明显的影响,所有优化页面加载速度成为很多公司追求的目标。SPDY旨在缩短网页的加载时间和提高安全性,SPDY的目标之一就是减少50%的加载时间
how?怎么样来达到缩短页面加载时间的目标呢?
1. 多路复用 请求优化
SPDY 规定在一个 SPDY 连接内可以有无限个并行请求,即允许多个并发 HTTP 请求共用一个 TCP会话。这样 SPDY 通过复用在单个 TCP 连接上的多次请求,而非为每个请求单独开放连接,这样只需建立一个 TCP 连接就可以传送网页上所有资源,不仅可以减少消息交互往返的时间还可以避免创建新连接造成的延迟,使得 TCP 的效率更高。
2 允许设置请求优先级
SPDY 的多路复用可以设置优先级,而不像传统 HTTP 那样严格按照先入先出一个一个处理请求,它会选择性的先传输 CSS 这样更重要的资源,然后再传输网站图标之类不太重要的资源,可以避免让非关键资源占用网络通道的问题,提升 TCP 的性能。
3 SPDY 压缩了 HTTP 头
舍弃掉了不必要的头信息,经过压缩之后可以节省多余数据传输所带来的等待时间和带宽。
what ?什么是SPDY
SPDY是Google开发的基于传输控制协议(TCP)的应用层协议 。Google最早是在Chromium中提出的SPDY协议,现为http2.0草案。SPDY协议通过压缩、多路复用和优先级来缩短加载时间。目前已经被用于Google Chrome浏览器中来访问Google的SSL加密服务,此外,Twitter、Facebook等著名公司也陆续部署SPDY服务。
SPDY 在原有协议栈上,增加了SPDY层,从而在单个TCP连接中,实现并发多个请求。传统的HTTP GET和POST消息格式保持不变,但中SPDY会指定一个新的帧格式进行编码和通过线路传输的数据。
SPDY的核心是帧管理层(framing layer),它管理两个端点间的连接和数据的传输。 两个端点之间可以有多个数据流。 在帧管理层的顶部,SPDY实现了HTTP请求/响应处理。这使得我们不需要对现有网站做太大的更改或不更改就可以使用SPDY。
在介绍SPDY工作流程前,先明确一下几个spdy引入的概念:
回话(session):等同与tcp连接
流:所有的请求和应答都是通过流进行的。一个SPDY会话可以拥有多条虚拟流,每条流都有标识其身份的流ID;
帧:SPDY协议中,数据传输的基本单位, SPDY帧可以分为控制帧和数据帧。控制帧用来建立流、关闭流等功能,数据帧用来传送数据。
当用户请求打开一个网页,SPDY会话层会向web服务器发起一个tcp连接,(在spdy协议中所有的tcp连接都是长连接,客户端一般不会断开连接,除非用户离开当前页面,跳向另一个页面,连接的断开由服务器负责,服务器会关掉那些长时间处于空闲的连接),建立tcp连接后,客户端和服务器就会开始进行帧的交互。
首先客户端为了发送http请求,需要与服务端建立虚拟流连接,建立流连接的过程和tcp建立连接的过程很相似,如上图所示,客户端发送SYN_STREAM控制帧,服务器收到SYN_STREAM帧后将回复SYN_REPLY帧表示连接建立,这里要注意的是,客户端不需要等待SYN_REPLY帧,就可以直接在该条流上发送数据帧。
当连接建立后,双方就可以在流上用数据帧发送数据了,数据帧中有一个字段表明此数据帧属于哪个虚拟流。当一方发送数据完毕后,就可以发送一个带有FIN_FLAG标志的帧,表示不会在该流上发送数据,流连接处于半关闭状态,如果双方都处于半关闭状态时,流就会被认为结束了,另外有个FIN_STREAM控制帧用于主动或者异常情况下结束流的传输。
另外SPDY还存在其他几种控制帧,比如Hello控制帧用于在连接建立后双发交换通讯细节,ping帧用于衡量双方数据传输的往返延迟等等。
http 头部压缩
SYN_STREAM 控制帧的格式
+------------------------------------+
|1| version | 1 |
+------------------------------------+
| Flags (8) | Length (24 bits) |
+------------------------------------+
|X| Stream-ID (31bits) |
+------------------------------------+
|X| Associated-To-Stream-ID (31bits) |
+------------------------------------+
| Pri|Unused | Slot | |
+-------------------+ |
| Number of Name/Value pairs (int32) | <+
+------------------------------------+ |
| Length of name (int32) | | 这里是 "Name/Value
+------------------------------------+ | Header Block", 是经过gzip压缩的.
| Name (string) | |
+------------------------------------+ |
| Length of value (int32) | |
+------------------------------------+ |
| Value (string) | |
+------------------------------------+ |
| (repeats) | <+
从这里可以看到,http 报文头部信息在spdy 中时经过压缩的
另外,除了像HTTP的网页服务器被动的等待浏览器发起请求外,SPDY的网页服务器还可以主动推送内容。
实现方式:
node-spdy 、 Apache mod_spdy、 Nginx SPDY Patch 、jetty
使用node-spdy 编写服务器的流程:
1 安装openssl,nodejs,npm install spdy
2 准备ssl证书,或使用示例代码中的证书
通过连接:https://localhost:443 ,可以看到运行效果。
这是从chrome://net-internals/#spdy 的截图:
参考:
http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3#TOC-1.-Overview
http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3#TOC-2.2.2-Data-frames
http://zh.wikipedia.org/wiki/SPDY
http://dev.chromium.org/spdy/spdy-whitepaper
http://blog.csdn.net/zxgfa/article/details/7436482
http://blog.csdn.net/zxgfa/article/details/7479052