探究Google SPDY

1.HTTP协议的不足

1)单路连接

     最初的HTTP 1.0规范规定了在每一个单独的请求/相应之后都必须关闭与服务器间的连接:也就是说连接无法重用,必须为每次请求重新创建一条新的TCP连接。

     HTTP 1.1的最大改变就是针对这个问题的:将连接默认为"keep-alive",并且介绍了一个"pipelining"的特性,keep-alive可以在多个请求之间重用TCP连接,而pipelining则允许一次发起多个请求。如今,keep-alive已经被大部分服务器和客户端所接受,但是pipelining却在大多数浏览器中被默认禁用(除了opera)。

     尽管如此,即使部署了pipelining支持,但HTTP严格限制请求必须以FIFO的方式被处理,因此如果在请求队列中有一个非常慢的动态请求,那么与它共用同一TCP通道的其它请求都必须等待这个请求先处理完成。


                       

 

2)只允许客户端主动发起请求

     在HTTP协议中,只允许客户端发起请求。即使在服务器知道客户端需要的资源,也只能等待客户端主动请求相应的资源。

3)HTTP头冗余及未压缩

     HTTP 头在同一个会话里是反复发送的,中间的冗余信息,比如 User-Agent、Host 等不需要重复发送的信息也在反复发送,另外HTTP头没有被压缩,浪费带宽和资源。

扫描二维码关注公众号,回复: 670181 查看本文章

2.SPDY 结构及特性

    SPDY 协议只是在性能上对 HTTP 做了很多的优化,其核心思想是复用TCP连接,SPDY对于 HTTP 的语义并没有修改,只是修改了传送HTTP内容的方式。

    1)SPDY实现

         SPDY强制使用SSL协议,SDPY在SSL之上增加了Session层,用来实现多路复用,在一个TCP连接中交错发送多个流(streams)。     

 


                 

 

 

   2)SPDY特性

        i)基本特性

           多路复用:SPDY 规定在一个 SPDY 连接内可以有无限个并发请求,即允许多个并发 HTTP 请求共用一个 TCP会话;

           请求优先级:SPDY 可以设置请求优先级,而不像HTTP 那样严格按照FIFO处理请求,它会优先传输重要的资源,这样可以避免让非关键资源占用网络通道的问题,提升性能;

           HTTP头压缩:舍弃掉了不必要的头信息,并对头信息进行压缩,降低数据传输量。

        ii)高级特性:
           服务器推送(server push):服务器可以主动向客户端推送数据,适合在初始页面时使用。例如,用户访问平安主页,当服务器收到用户的请求后,可直接向用户推送主页上的css,js,图片等资源,不需要像HTTP那样等用户收到页面,解析页面后再逐一向服务端请求。

           服务器提示(server hint) : 服务器建议客户端应该请求某些资源,适合在非初始页面时使用。该特性中,服务器是不能主动向客户端发送数据的。 

3.具体实现

   SPDY是建立在TCP可靠传输之上的,并且是长连接。

   SPDY标准包含两层,framing layer和HTTP layer。framing layer使用帧来实现TCP连接的多路复用;HTTP layer定义了在framing layer之上实现HTTP请求和响应的机制。

   在浏览器中访问Google主页,对比其在HTTP和SPDY协议下的实现,来说明SPDY怎样实现多路复用,优先级设定等特性,下图为HTTP实现与SPDY实现流程对比。


    1)SPDY framing layer

        SPDY在Framing layer定义了两种帧,控制帧和数据帧。通过这两种帧,可实现全双工流(stream),SPDY中的每个请求都有一个stream ID,服务器和客户端之间可以再单个TCP通道并行传输数据,在同一时间通过同一个通道响应多个资源请求,只需要识别出数据对应的stream就可以了。例如,上图中,使用SPDY协议向google服务器分别请求CSS,请求图片,都是一个stream,这些stream可以并发,每个流有不同的stream_id,用来区分不同的请求及其响应。

 


                                      

        为了管理一个stream,SPDY定义了三种控制帧,分别为:

        i)SYN_STREAM:创建一个新的stream。

        ii)SYN_REPLY:响应一个stream。

        iii)RST_STREAM:关闭一个steam。

    2)SPDY实现(无服务器推)

        客户端向服务器请求CSS:

        i)客服端发送SYN_STREAM创建一个新的stream,用来请求CSS。

          在SYN_STREAM帧中,使用Stream_ID来唯一标识该stream,并在Priority标志位说明该请求的优先级,优先级从0-7逐渐降低,服务器会首先处理优先级高的stream。

          在Name/Value Header blocker,这部分用来存储HTTP报头内容,例如cookie,host等等,并使用gzip进行压缩。

          stream的创建是异步的,在发送了SYN_STREAM创建流之后,不需要等待服务器回应,可立即发送数据帧。数据帧的Stream_ID需要与创建流控制帧的Stream_ID相同,Data所存储的内容即是HTTP报文的body部分。

        ii)服务端使用SYN_REPLY帧响应stream请求:

           服务端收到创建流的帧之后,对请求进行处理并响应,发送SYN_REPLY帧到客户端,应答帧的Stream_ID字段应该与创建帧的Stream_ID的字段相同,以便在客户端收到应答帧之后确认是对哪个请求的应答。

          与SYN_STREAM创建帧类似,应答帧SYN_REPLY也有Name/Value Header blocker,用来存储HTTP报文头。在应答帧发送之后的数据帧,用来传送HTTP报文的body内容。

        iii)发送RST_STREAM关闭流。

          Stream_ID字段表示要关闭的流。

     3)SPDY实现(服务器推)

        当客户访问Google主页时,客户端会创建一个流,该流的Stream_ID为5,当服务器收到创建流的控制帧之后,知道客户要访问Google主页,同时,服务端知道客户端主要需要的其他资源,如CSS,js,图片等。服务器可以主动创建流将这些资源发送到客户端。

        服务端向客户推送这些资源时,创建的流associated_stream_id说明了这个push stream对应哪个请求流。服务器推送CSS,js,图片分别创建三个不同的流,其流创建帧的associated_stream_id要为请求Google主页创建流的stream_id。

猜你喜欢

转载自wy1208.iteye.com/blog/1622355