Spdy
Http的缺陷
- 一个连接处理一个请求:http建立的一个链接只能处理一个http请求,多个请求需要建立多个http的链接。每次的链接建立都会增加RTT的时间。
- Http对请求是严格的FIFO处理方式,即使中间某个请求的处理时间很长,也会阻塞后面的请求;
HTTP pipelining
可改善链接的效率,但是成本很大
- Http只允许客户端发起请求
- 未压缩的请求头/响应头:减少头信息可以很明显的降低延时
- 冗余的头信息:Http的头信息会在一个会话(Session)中反复的发送,比如 User-Agent、Host 等不需要重复发送的信息也在反复发送,浪费带宽和资源。
- 可选的数据压缩:http的数据压缩是默认不开启的。
Spdy的设计
Spdy的设计是在SSL/TLS上增加一个Session层,从而实现在一个链接上的多请求的并发处理。
核心术语
- connection:两端之间传输层的链接
- session:connection的同义词。
- frame:包含header前缀的字节流,在SPDY session上进行传输。
- stream:在SPDY session中的双向的字节流虚拟通道。
- client:SPDY session中初始化发起的端
- server:SPDY session中非初始化发起
Session是长连接的,一个Session与一个TCP链接一一对应;frame一旦建立链接,客户端和服务端就可以交换帧消息了。分为:控制帧
和数据帧
;stream就是由多个相关联的frame组成,一个stream只能用于传输一次HTTP请求及该请求对应的HTTP响应。
SPDY分为两层:Framing Layer
和HTTP Layer
。Framing Layer位于TCP协议层之上,传输的数据单元是frame,同一个TCP连接可以传输多个独立的frame。HTTP Layer则位于Framing Layer之上,负责把HTTP协议与SPDY协议的转换。
Framing 帧
控制帧(Control Frames)
- 控制位(Control bit): 'C'位用一个比特定义控制消息,控制帧的值恒定1;
- 版本(Version):SPDY协议的版本号;
- 类型(Type):控制帧的类型;
- SYN_STREAM:允许发送者在两端之间异步的创建stream;
- SYN_REPLY:接收一个由SYN_STREAM帧接受者创建的流是的回应
- RST_STREAM:不正常终止一个流,两端都可以发送这个控制流
- SETTINGS:包含一组id/value对的配置数据来告诉两端可以怎样通信,可以被任何端发送,选择性发送,并且是全异步的。settings可以被持久化,是由client持久化的。
- PING:是一种测试发送者最小round-trip时间的机制。可以被两端发送,ping frame的优先级是最高的。
- GOAWAY:是一种通知连接的远端在这个会话上停止创建流的机制,可以被任何端发送,一旦发送,发送端将不再创建新的stream,接受端也不再发送stream。
- HEADERS:对stream商议额外的头信息,可选的。
- WINDOW_UPDATE:在SPDY中用于实现流量的控制
- 标识(Flags):和这个帧有关的标识。控制帧和数据帧的标识不同;
- 长度(Length):一个无符号24bit数字表示之后域的长度;
- 数据(Data):控制帧相关的数据。格式和长度取决于控制帧的类型。
SYN_STREAM
- Flags:标识位
- FLAG_FIN:将此frame作为stream里最后一个,并且使发送端处于半关闭状态;
- FLAG_UNIDIRECTIONAL:使接受端处于半关闭状态
- Stream-ID:标示stream的31位标识符
- Associated-To-Stream-ID:关联这个stream的31位标示符。
- Priority:保留
- Unused:保留
- Slot:保留
SYN_REPLY
- Flags:标识位
- FLAG_FIN:将此frame作为stream里最后一个,并且使发送端处于半关闭状态;
RST_STREAM
- Flags:0
- Status code:指示这个流被终止的原因。
- 1 - PROTOCOL_ERROR:通用error
- 2 - INVALID_STREAM:stream不在是有效的
- 3 - REFUSED_STREAM:被拒绝的stream
- 4 - UNSUPPORTED_VERSION:不支持当前version的stream
- 5 - CANCEL:由创建者发起,指示这个stream不再使用
- 6 - INTERNAL_ERROR:通过error,协议的实现者内部错误
- 7 - FLOW_CONTROL_ERROR:冲突
- 8 - STREAM_IN_USE:
- 9 - STREAM_ALREADY_CLOSED:接收端将进入半关闭状态
- 10 - unused
- 11 - FRAME_TOO_LARGE:
SETTINGS
PING
client发送时,使用奇数的ID,server发送时,使用偶数的ID。PING的frame长度是不变的,都是4bytes。
GOAWAY
GOAWAY的frame的长度是固定8bytes的。
- Last-good-stream-Id:指的是这个session中最后一个创建的stream的steam_id值。没有的话,就是0
- Status:关闭Session的原因
- 0 - OK
- 1 - PROTOCOL_ERROR
- 2 - INTERNAL_ERROR
HEADERS
协商头信息的name/value是被压缩传输的。
WINDOW_UPDATE
流量控制包括两个级别:单个的stream、整个的connection/session。
并且流量控制是逐段的,就是说只在两个端之间有效。
长度也是固定为8,stream-ID非0就是正对特定的stream。
SPDY总结
特性
- 流复用:允许一个TCP里面无线的并发流处理,各个请求是在一个单一的通道下交错传输,从而减少网络连接的需要;
- 请求优先级:虽然无限的并行数据流解决了序列化问题,但是它们引入了另一个问题:如果由于信道带宽的限制,客户端可能会阻止怕堵塞通道的要求。为了克服这个问题,SPDY实现请求的优先次序:客户端可以请求尽可能多的项目,每个请求分配一个优先级。这样 即使高优先级的请求仍处在pending状态,通道也不会传输非关键的,低优先级的请求,这样就有效地阻止了传输拥塞。
- Http header压缩:对于HTTP 请求,响应头,SPDY都做了压缩,这样包更小。
- 服务器端推送:SPDY通过X-Associated-Content 协议头来向客户端推送数据。
- 安全:默认开启的SSL。
- Server hint:这个类似于服务器推送,差别在于它不会实际的推送消息,而是告知浏览器有这个消息,仍旧等待客户端的请求,对于低速网络,是个很大的优化,有点类似于我们的预加载技术。
工作机制
- session--会话,一个SPDY会话实质上就是一个tcp连接。
- stream--虚拟流,一个SPDY会话可以拥有多条虚拟流,每条流都有标识其身份的流ID,所有的请求和应答都是通过流进行的
- frame--SPDY帧,在SPDY协议中,客户端和服务器交互的数据就是SPDY帧,SPDY帧可以分为控制帧和数据帧,数据帧和控制帧通过帧的第一个比特位进行区分,
帧格式的整理参考:
普通的一个SPDY流程: