http2 協(xié)議
HTTP/2 源自 SPDY/2褥芒,正式版http2規(guī)格標(biāo)準(zhǔn)叫做RFC 7540,發(fā)布于2015年5月15日。
HTTP/2 跟 SPDY 仍有不同的地方,主要是以下兩點(diǎn):
HTTP/2 支持明文 HTTP 傳輸驹针,而 SPDY 強(qiáng)制使用 HTTPS
HTTP/2 消息頭的壓縮算法采用 HPACK,而非 SPDY 采用的 DELEFT
http2 特點(diǎn)
http2 性能诀艰,http2 demo
HTTP/2's binary framing layer
Streams, messages, and frames
Request and response multiplexing
Stream prioritization
One connection per origin
Flow control
Server push
Header compression
(1)二進(jìn)制
HTTP/2 采用二進(jìn)制格式傳輸數(shù)據(jù)
柬甥,而非 HTTP/1.x 的文本格式墙牌。二進(jìn)制協(xié)議解析起來更高效。
(2)二進(jìn)制格式
HTTP/1 的請(qǐng)求和響應(yīng)報(bào)文暗甥,都是由起始行、首部和實(shí)體正文(可選)組成捉捅,各部分之間以文本換行符分隔撤防。
HTTP/2 將請(qǐng)求和響應(yīng)數(shù)據(jù)分割為更小的幀,并對(duì)它們采用二進(jìn)制編碼棒口。
幀(Frame):HTTP/2 數(shù)據(jù)通信的最小單位寄月。
消息(Message):指 HTTP/2 中邏輯上的 HTTP 消息。例如請(qǐng)求和響應(yīng)等无牵,消息由一個(gè)或多個(gè)幀組成
流(Stream):存在于連接中的一個(gè)虛擬通道漾肮。流可以承載雙向消息,每個(gè)流都有一個(gè)唯一的整數(shù) ID茎毁。
HTTP/2 中克懊,同域名下所有通信都在單個(gè)連接上完成,這個(gè)連接可以承載任意數(shù)量的雙向數(shù)據(jù)流七蜘。每個(gè)數(shù)據(jù)流都以消息的形式發(fā)送谭溉,而消息又由一個(gè)或多個(gè)幀組成。多個(gè)幀之間可以亂序發(fā)送橡卤,因?yàn)楦鶕?jù)幀首部的流標(biāo)識(shí)可以重新組裝扮念。
Frame 是 HTTP/2 二進(jìn)制格式的基礎(chǔ),F(xiàn)rame 的基本格式如下
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
字段含義可查看協(xié)議
(3)多路復(fù)用
HTTP/1.X 存在線端阻塞(head-of-line blocking)的問題碧库。HTTP/1.1 試過用流水線(pipelining)來解決這個(gè)問題, 但是效果并不理想(數(shù)據(jù)量較大或者速度較慢的響應(yīng), 會(huì)阻礙排在他后面的請(qǐng)求)柜与。HTTP 管道技術(shù)無法大規(guī)模使用。
多路復(fù)用嵌灰,代替原來的序列和阻塞機(jī)制弄匕。就是所有的請(qǐng)求都是通過一個(gè) TCP
連接并發(fā)完成。流支持優(yōu)先級(jí)
和流量控制
伞鲫。
HTTP/2 的多路復(fù)用特性粘茄,使得可以在一個(gè)連接上同時(shí)打開多個(gè)流,雙向傳輸數(shù)據(jù)秕脓。每次請(qǐng)求/響應(yīng)使用不同的 Stream ID柒瓣。通過 Stream ID 標(biāo)識(shí),所有的請(qǐng)求和響應(yīng)都同時(shí)跑在一條 TCP 鏈接上吠架。 當(dāng)流并發(fā)時(shí)芙贫,就會(huì)涉及到流的優(yōu)先級(jí)和依賴。優(yōu)先級(jí)高的流會(huì)被優(yōu)先發(fā)送傍药。圖片請(qǐng)求的優(yōu)先級(jí)要低于 CSS 和 SCRIPT磺平,這個(gè)設(shè)計(jì)可以確保重要的東西可以被優(yōu)先加載完魂仍。http2上面每個(gè)流都擁有自己的公示的流量窗口,它可以限制另一端發(fā)送數(shù)據(jù)拣挪。
(4)頭壓縮
HTTP 1.1請(qǐng)求的大小變得越來越大擦酌,有時(shí)甚至?xí)笥赥CP窗口的初始大小,這會(huì)嚴(yán)重拖累發(fā)送請(qǐng)求的速度菠劝。因?yàn)樗鼈冃枰却龓е鳤CK的響應(yīng)回來以后赊舶,才能繼續(xù)被發(fā)送。
HTTP/2 對(duì)消息頭采用 HPACK (專為http2頭部設(shè)計(jì)的壓縮格式)進(jìn)行壓縮傳輸赶诊,能夠節(jié)省消息頭占用的網(wǎng)絡(luò)的流量笼平。而 HTTP/1.x 每次請(qǐng)求,都會(huì)攜帶大量冗余頭信息舔痪,浪費(fèi)了很多帶寬資源寓调。
(5)服務(wù)端推送
服務(wù)端可以在發(fā)送頁面 HTML 時(shí)主動(dòng)推送其它資源,而不用等到瀏覽器解析到相應(yīng)位置锄码,發(fā)起請(qǐng)求再響應(yīng)夺英。例如服務(wù)端可以主動(dòng)把 JS 和 CSS 文件推送給客戶端,而不需要客戶端解析 HTML 再發(fā)送這些請(qǐng)求滋捶。
服務(wù)端可以主動(dòng)推送秋麸,客戶端也有權(quán)利選擇接收與否。如果服務(wù)端推送的資源已經(jīng)被瀏覽器緩存過炬太,瀏覽器可以通過發(fā)送 RST_STREAM 幀來拒收灸蟆。
瀏覽器和web服務(wù)支持情況
安裝部署
從 Nginx 1.9.5 開始,http_v2_module 已經(jīng)替換了 ngx_http_spdy_module亲族,安裝版本用1.10.1
nginx
./configure --with-http_v2_module
mac
brew options nginx
brew install nginx --with-http2
配置https
HTTP/2 協(xié)議本身并沒有要求必須基于 TLS 部署炒考,但是 Chrome 和 Firefox 均表示只支持 HTTP/2 Over TLS。一方面更安全霎迫,希望保護(hù)以及尊重用戶的隱私斋枢,一方面利用 TLS 的加密機(jī)制可以更好地穿透網(wǎng)絡(luò)中間節(jié)點(diǎn)。需要先配置https知给。
# 創(chuàng)建一個(gè)私鑰文件:
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl rsa -in server.key -out server_nopass.key
# 結(jié)合密鑰和證書生成請(qǐng)求瓤帚,創(chuàng)建一個(gè)自簽署的CA證書
openssl req -new -x509 -days 3650 -key server_nopass.key -out server.crt
配置nginx
server
{
listen 443 ssl http2;
server_name www.kailian.com;
index index.php index.html;
root /data/web/www;
ssl on;
ssl_certificate /usr/local/etc/nginx/server.crt;
ssl_certificate_key /usr/local/etc/nginx/server_nopass.key;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
keepalive_timeout 70;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
charset utf-8;
location ~ .*\.php$
{
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}
測(cè)試
ssllabs查看https配置是否夠快
在 Chrome 地址欄輸入chrome://net-internals/#http2
,打開 Chrome 自帶的 HTTP/2 查看工具涩赢,可查看 HTTP/2 幀信息
Wireshark抓包查看