http2 協議
HTTP/2 源自 SPDY/2,正式版http2規格標準叫做RFC 7540,發布于2015年5月15日。
HTTP/2 跟 SPDY 仍有不同的地方,主要是以下兩點:
HTTP/2 支持明文 HTTP 傳輸,而 SPDY 強制使用 HTTPS
HTTP/2 消息頭的壓縮算法采用 HPACK,而非 SPDY 采用的 DELEFT
http2 特點
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)二進制
HTTP/2 采用二進制格式傳輸數據
,而非 HTTP/1.x 的文本格式。二進制協議解析起來更高效。
(2)二進制格式
HTTP/1 的請求和響應報文,都是由起始行、首部和實體正文(可選)組成,各部分之間以文本換行符分隔。
HTTP/2 將請求和響應數據分割為更小的幀,并對它們采用二進制編碼。
幀(Frame):HTTP/2 數據通信的最小單位。
消息(Message):指 HTTP/2 中邏輯上的 HTTP 消息。例如請求和響應等,消息由一個或多個幀組成
流(Stream):存在于連接中的一個虛擬通道。流可以承載雙向消息,每個流都有一個唯一的整數 ID。
HTTP/2 中,同域名下所有通信都在單個連接上完成,這個連接可以承載任意數量的雙向數據流。每個數據流都以消息的形式發送,而消息又由一個或多個幀組成。多個幀之間可以亂序發送,因為根據幀首部的流標識可以重新組裝。
Frame 是 HTTP/2 二進制格式的基礎,Frame 的基本格式如下
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
字段含義可查看協議
(3)多路復用
HTTP/1.X 存在線端阻塞(head-of-line blocking)的問題。HTTP/1.1 試過用流水線(pipelining)來解決這個問題, 但是效果并不理想(數據量較大或者速度較慢的響應, 會阻礙排在他后面的請求)。HTTP 管道技術無法大規模使用。
多路復用,代替原來的序列和阻塞機制。就是所有的請求都是通過一個 TCP
連接并發完成。流支持優先級
和流量控制
。
HTTP/2 的多路復用特性,使得可以在一個連接上同時打開多個流,雙向傳輸數據。每次請求/響應使用不同的 Stream ID。通過 Stream ID 標識,所有的請求和響應都同時跑在一條 TCP 鏈接上。 當流并發時,就會涉及到流的優先級和依賴。優先級高的流會被優先發送。圖片請求的優先級要低于 CSS 和 SCRIPT,這個設計可以確保重要的東西可以被優先加載完。http2上面每個流都擁有自己的公示的流量窗口,它可以限制另一端發送數據。
(4)頭壓縮
HTTP 1.1請求的大小變得越來越大,有時甚至會大于TCP窗口的初始大小,這會嚴重拖累發送請求的速度。因為它們需要等待帶著ACK的響應回來以后,才能繼續被發送。
HTTP/2 對消息頭采用 HPACK (專為http2頭部設計的壓縮格式)進行壓縮傳輸,能夠節省消息頭占用的網絡的流量。而 HTTP/1.x 每次請求,都會攜帶大量冗余頭信息,浪費了很多帶寬資源。
(5)服務端推送
服務端可以在發送頁面 HTML 時主動推送其它資源,而不用等到瀏覽器解析到相應位置,發起請求再響應。例如服務端可以主動把 JS 和 CSS 文件推送給客戶端,而不需要客戶端解析 HTML 再發送這些請求。
服務端可以主動推送,客戶端也有權利選擇接收與否。如果服務端推送的資源已經被瀏覽器緩存過,瀏覽器可以通過發送 RST_STREAM 幀來拒收。
瀏覽器和web服務支持情況
安裝部署
從 Nginx 1.9.5 開始,http_v2_module 已經替換了 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 協議本身并沒有要求必須基于 TLS 部署,但是 Chrome 和 Firefox 均表示只支持 HTTP/2 Over TLS。一方面更安全,希望保護以及尊重用戶的隱私,一方面利用 TLS 的加密機制可以更好地穿透網絡中間節點。需要先配置https。
# 創建一個私鑰文件:
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
# 結合密鑰和證書生成請求,創建一個自簽署的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;
}
}
測試
ssllabs查看https配置是否夠快
在 Chrome 地址欄輸入chrome://net-internals/#http2
,打開 Chrome 自帶的 HTTP/2 查看工具,可查看 HTTP/2 幀信息
Wireshark抓包查看