HTTP 協議的最大弊端就是每一個 TCP 鏈接只能對應一個 HTTP 請求,即每一個 HTTP 鏈接只請求一個資源,瀏覽器只能經過創建多個鏈接來解決。此外在 HTTP 中對請求是嚴格的先入先出(FIFO)進行的,若是中間某個請求處理時間較長會阻塞後面的請求html
服務端只能等待客戶端發送一個請求,在能夠知足預加載的現狀是一種桎梏nginx
HTTP 頭在同一個會話裏是反覆發送的,中間的冗餘信息,好比 User-Agent、Host 等不須要重複發送的信息也在反覆發送,浪費帶寬和資源算法
HTTP1.0/1.1在數據傳輸中使用的是明文,攻擊者很容易獲取數據內容chrome
有必定的費用瀏覽器
性能問題緩存
除了安全之外,不能解決HTTP1.0/1.1其餘的問題安全
SPDY是Google公司2012年發佈的基於TCP/IP的應用層協議。SPDY協議經過壓縮、多路複用和優先級來縮短網頁的加載時間和安全性。
SPDY是Speedy的音,是更快的意思。服務器
SPDY 協議只是在性能上對 HTTP 作了很大的優化,其核心思想是儘可能減小鏈接個數,而對於 HTTP 的語義並無作太大的修改。具體來講是,SPDY 使用了 HTTP 的方法和頁眉,可是刪除了一些頭並重寫了 HTTP 中管理鏈接和數據轉移格式的部分,因此基本上是兼容 HTTP 的。
Google 在 SPDY 白皮書裏表示要向協議棧下面滲透並替換掉傳輸層協議(TCP),可是由於這樣不管是部署起來仍是實現起來暫時至關困難,所以 Google 準備先對應用層協議 HTTP 進行改進,先在 SSL 之上增長一個會話層來實現 SPDY 協議,而 HTTP 的 GET 和 POST 消息格式保持不變,即現有的全部服務端應用均不用作任何修改。cookie
不論是普通用戶仍是開發者均可以像使用HTTP同樣使用SPDY。session
如上圖SPDY位於HTTP之下,TCP和SSL之上
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 |
+----------------------------------+
各數據位的意義:
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種類型及做用:
單鏈接多路複用
在同一個域名下,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爲了安全強制使用安全協議,經過壓縮和優先級策略來彌補安全協議的性能問題
多域名請求下一樣要創建多條鏈接
SSL/TLS協議的性能問題
全部頭部名都須要小寫
客戶端必須支持 gzip 壓縮
Google已經再也不支持SPDY
國內使用SPDY的大廠是阿里,還開源了一款基於Nginx的服務器Tengine。
wget http://tengine.taobao.org/download/tengine-2.1.2.tar.gz
- ./configure --prefix=/data/tengine --with-http_spdy_module --with-http_v2_module
- make
- make install
先生成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; } }
./nginx
最新的chrome中已經不支持SPDY了,所以在firefox中進行驗證。
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,目的是在開放互聯網上增長使用加密技術,以提供強有力的保護去遏制主動攻擊。護自行發行證書。
HTTP2.0是SPDY的升級,它採用了SPDY不少的特性和技術,但和SPDY有明顯的區別:
如上圖,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
如上圖,客戶端和服務端創建了一條TCP鏈接,每一個stream都有一個ID,相同的ID表示是同一個資源。
創建鏈接階段
客戶端同服務端創建一條TCP鏈接,若是使用SSL/TLS,將創建一條加密的鏈接
請求數據階段
客戶端向服務端請求數據,發送一個frame,同一域名下的請求都會經過該鏈接發送到服務端
響應數據階段
服務端向客戶端響應數據,若是發現有其餘的數據請求,經過同一TCP鏈接主動向客戶端推送資源
多路複用
同SPDY同樣,HTTP2.0支持多路複用,能在單一TCP鏈接中進行數據的傳輸
header壓縮
同SPDY同樣,爲了減小報文頭的數據量,HTTP2.0也支持header的壓縮。但爲了防止BREACH4和CRIME攻擊,採用HPACK6對頭部進行壓縮
服務端推送
HTTP2.0一樣提供了服務器推送技術
優先級和依賴關係
每一個流都有本身的優先級別,會代表哪一個流是最重要的,客戶端會指定哪一個流是最重要的,有一些依賴參數,這樣一個流能夠依賴另一個流
重置
HTTP2.0引入了一個 RST_STREAM frame 來讓客戶端在已有的鏈接中發送重置請求,從而中斷或者放棄響應。當瀏覽器進行頁面跳轉或者用戶取消下載時,它能夠防止創建新鏈接,避免浪費全部帶寬。
流量控制
HTTP2.0每一個獨立流都有流控制,但只有DATA Frame才受控制。接收端通知發送方還能接收多少數據來控制。
一樣經過Tengine來部署HTTP2.0,下載和安裝見SPDY的實踐。
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; } }
./nginx -s reload
在此過程當中,要注意chrome瀏覽器的版本,若是大於51,則須要服務器使用openssl的alpn
下載openssl-1.0.2 而後從新編譯時加入 --with-openssl=path
移動端
最新版本移動端(IOS和Android)都支持SPDY和HTTP2.0,但較低版本的不支持HTTP2.0,但可使用SPDY進行過渡
網頁應用
最新的Chrome已經不支持SPDY
多域名
對大型網站和靜態資源(圖片、JS/CSS文件等等)分離的網站,可能不僅一個域名,這時也會創建多個鏈接
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