1 SPDY協議1.1 概述
SPDY為speedy(單詞原意:快速的)的縮寫,讀音也就是speedy。
SPDY協議發行過4個草案,分別為版本1、2、3、3.1。目前版本4已在實驗階段,但未發布,Chromium裡已有一些針對版本4的代碼。
SPDY對比HTTP的優勢:
缺點:
由於這些缺點,SPDY在小網站(資源檔數量較少)的效果不明顯,有可能比多並發串連更慢。(由此催生了QUIC)
1.2 協議層次
基於安全的考慮,SPDY規定建立在TLS之上,即URL scheme為https。發明者表示TLS的握手是在一定程度上佔用了時間和流量,但網路安全是必然的趨勢,所以不計較這一成本。協議層次如下:
SPDY ← HTTP ↓ TLS ← NPN ↓ TCP
對比普通的HTTPS協議層次:
HTTP ↓ SSL/TLS ↓ TCP
SPDY協議雖然在TLS基礎上代替了HTTP協議,但SPDY的內容又包含了HTTP協議的內容,用設計模式來理解就是應用裝飾者模式擴充了HTTP。
另外為了在TLS之上不使用標準規定的HTTP協議,為TLS擴充出NPN(Next Protocol Negotiation,協議協商)。
1.3 NPN
NPN簡單來說就是在TLS的握手階段增加一些欄位來表明伺服器端和用戶端希望在TLS基礎上使用HTTP之外的(SPDY)協議。NPN同樣是Google提出的,為SPDY鋪路。
Client端程式的實現是:握手前對OpenSSL(或封裝它的庫)設定可接受哪些協議,握手後擷取選擇了哪個協議,然後按選擇的協議進行通訊。
1.4 資料格式
本節不會完整介紹SPDY,只講重點,並假定讀者熟悉HTTP協議而不解釋SPDY中類似HTTP的概念。
SPDY把一次單向傳輸(伺服器到用戶端或用戶端到伺服器)的內容稱作幀(frame),按協議組裝幀內容稱為裝幀(framing)。幀內容分為頭部(header)和載荷(payload),類似於HTTP的頭部(header)和實體(entity),但有以下區別:
根據載荷的內容,幀分為控制幀和資料幀。
控制幀的資料格式:
+----------------------------------+|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種類型及作用:
為幀格式的整理參考(需對照協議文檔來理解具體意義,可跳過,點擊查看大圖):
1.5 流程
普通流程如:
Server Push的server端流程:回複client端的SYN_STREAM之後,再在server端發起SYN_STREAM,並在payload中用欄位Associated_To_Stream_ID表示這個推送與哪個stream關聯。
2 HTTP/22.1 概述
HTTP/2准第11版草案於2014年3月17日更新在http://http2.github.io/http2-spec/。
HTTP/2由標準化組織來制定,是基於SPDY的,差別是:
HTTP/2文檔帶有一些樣本和詳細說明,這是SPDY沒有的。
Chromium最新代碼和Google網站已支援HTTP2-10(HTTP/2第10版草案)。
2.2 ALPN
ALPN第5版草案於2014年3月3日發布在http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-05。 它是基於NPN的,並做了流程最佳化,但原則沒變,就是在TLS握手過程增加一種協商協議的手段。標準流程為:
Client Server ClientHello --------> ServerHello (ALPN extension & (ALPN extension & list of protocols) selected protocol) Certificate* ServerKeyExchange* CertificateRequest* <-------- serverhellodone certificate* clientkeyexchange* certificateverify* [changecipherspec] finished --------> [ChangeCipherSpec] <-------- Finished Application Data <-------> Application Data
目前Chromium的PC發布版已經在使用ALPN,不用NPN了。
2.3 TCP上的應用
HTTP/2可使用http或https scheme作為URL。
當使用http scheme時,client先用HTTP/1.1的request發給server,但要加入header Upgrade和HTTP2-Settings。格式為:
GET /default.htm HTTP/1.1Host: server.example.comConnection: Upgrade, HTTP2-SettingsUpgrade: h2cHTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>
如果server支援HTTP/2,則以狀態代碼101回複,形式如下:
HTTP/1.1 101 Switching ProtocolsConnection: UpgradeUpgrade: h2[ HTTP/2 connection ...
然後雙方開始以HTTP/2作為傳輸協議。否則以HTTP/1.1回複response,即HTTP/1.1 200 OK。
3 QUIC
QUIC是Quick UDP Internet Connections的縮寫,讀作quick。由Google開發,概要設計文檔放在google docs https://docs.google.com/document/d/1RNHkx_VvKWyWg6Lr8SZ-saqsQx7rFV-ev2jRFUoVD34/edit,還在不斷更新。傳輸格式的詳細設計文檔放在https://docs.google.com/document/d/1WJvyZflAO2pq77yOLbp9NsGjC1CHetAXV8I0fQe-B_U/edit。
概要設計文檔從TCP/UDP特性、網路安全等考慮出發,做了非常多設計思路方面的論述,開頭就闡述了SPDY的4個缺點:
可以認為QUIC是為瞭解決SPDY在TCP遇到的瓶頸而在UDP上做探索所設計的方案。參考SPDY來理解,可認為QUIC的傳輸內容分兩層,高層類似SPDY,低層是在UDP上模仿實現TCP的連線導向特性和可靠性並加入類似TLS的加密過程。
QUIC的文檔還算未完成的狀態,且Chromium的實現代碼也在完善中,這還是個實驗性的半成品,沒有效能比較的資料。只淺淺研究即止,不深入了。
轉載請註明出處:http://blog.csdn.net/hursing
4 研究與調查4.1 SPDY伺服器搭建4.1.1 Apache
具體的搭建方法請參考《Linux Mint + Apache2.2搭建SSL/HTTPS/SPDY伺服器》。
環境配置為Linux + Apache2.2 + mod_spdy。其中mod_spdy是Chromium為Apache開發的外掛程式,只支援Apache2.2,直接安裝外掛程式包即可。SPDY協議支援版本為3。
4.1.2 Nginx
具體的搭建方法請參考《Linux Mint + Nginx 1.5.11搭建SSL/HTTPS/SPDY伺服器》。
環境配置為Linux + Nginx1.5.11,需要編譯源碼來啟用SPDY,普通發布包並不支援。SPDY協議支援版本為3.1,還不支援Server Push。
4.1.3 份額
根據新聞網頁http://www.csdn.net/article/2013-07-04/2816099-nginx-just-became-the-most-used-web-server表示,在全球排名前1000的高流量網站所使用的Web伺服器中,Nginx佔34.9%,Apache佔34.5%。兩者分別排名第一和第二,第三的Microsoft-IIS並不支援SPDY。
4.2 Wireshark截包
Chromium為Wireshark1.7.1做了源碼patch,名為spdyshark,需要下載Wireshark源碼和spdyshark源碼共同編譯才能令Wireshark支援SPDY協議。具體的編譯安裝方法請參考《Linux Mint下編譯安裝支援SPDY協議的Wireshark》。
因為SPDY基於TLS,所以Wireshark截包需要先解密SSL,再解析SPDY協議。具體的截包方法請參考《Wireshark+Apache2.4解密SSLv3》和《使用支援SPDY協議的Wireshark截包(含spdyshark外掛程式)》。
4.3 Server端應用現狀4.3.1 調查方法
調查Web伺服器是否支援SPDY,可使用第三方網站的方法:訪問http://spdycheck.org/,在網頁中輸入網址即可反饋結果。例如:
但是國內網站並非全站都用HTTPS scheme,所以需要人工找到登入帳號的頁面來做測試。
還可使用Wireshark截包,在TLS的Server Hello資訊中找Extension,ALPN會顯示Unknown 16,NPN能識別出是Extension: next_protocol_negotiation。
可知目前Google網站用3.1:
Facebook用2和3:
4.3.2 調查結果國內外的常見網站看了看,只發現四家:Google、Facebook、wordpress.com和www.cloudflare.com。國內還沒有網站支援。(注,此調查結果很粗淺,不可當權威結論)4.4 Browser端應用現狀4.4.1 測試方法
用目標瀏覽器訪問https://isspdyenabled.com/即會在頁面上顯示是否支援SPDY。
4.4.2 資料
根據第三方資料,支援SPDY的瀏覽器有:
支援SPDY的瀏覽器佔65.26%。具體請參看http://caniuse.com/spdy。
搜尋到CNZZ統計了中國的瀏覽器份額,但無法直觀地看出支援SPDY的佔比,個人估算是案頭版低於50%,移動版低於30%。http://brow.data.cnzz.com/main.php?s=brow&uv=1&type=2&date=2014%E5%B9%B402%E6%9C%88。
5 瀏覽器實現方案
SPDY對瀏覽器的實現來說,工作在載入架構的網路層。假如已實現SPDY,描述網路層內部再分層細化以及各細化層的職責:
無論是HTTP還是SPDY,在一次載入流程中都需要各細化層承擔所有的職責。在代碼實現來看,若HTTP和SPDY有不同,則需要對各職責設計基類,HTTP和SPDY各自繼承基類以實現不同的過程。
SPDY特殊實現的職責有:
除了Chromium自己外,其SPDY文檔還列出了幾種實現。C/C++的其它實現,都有個共同點:因為工作在底層,依賴比較多的外部庫代碼。而且他們最近三個月都還有更新,多數並未支援所有的SPDY特性,並且在修複bug。所以代碼的完善程度還不能達到瀏覽器層級的標準。
6 網站是否該支援SPDY
暫無必要支援SPDY、HTTP/2和QUIC。
原因:
轉載請註明出處:http://blog.csdn.net/hursing