前段時間開始,公司各項業務開始陸續接入http2,關於http2的優點與所適用的場景網上有很多的文檔可以查閱,這里我主要是總結分享一下如何從0到1搭建http2服務。
這里先說明一下,要完成http2的請求需要客戶端和服務端同時支持,如下表格可以看出,只要客戶端或服務端任意一端不支持http2,都會自動降級到http1.1:
一、以下為客戶端(各瀏覽器)支持情況:
目前除了Opera Mini以及UC Browser for Android 以外,其他瀏覽器支持情況還算不錯,可是這些支持http2的瀏覽器也是有條件的,可以看到下圖中下面的1、2、4,主要是2和4:必須是https以及服務端要支持ALPN(應用層協議協商);詳細一點的服務端要求,請看下面。
二、以下為服務端要求:
google開發SPDY時提出了NPN(下一代協議協商),但隨着SPDY被HTTP/2取代,google漸漸放棄了NPN,而改為ALPN(應用層協議協商);從chrome51開始就移除了對NPN的支持,只保留了支持ALPN(因此服務端必須要支持ALPN)
1)OpenSSL 需要>=1.0.2的版本,因為也只有1.0.2或以上版本的OpenSSL才支持ALPN,而遺憾的是一般的Linux默認內置的OpenSSL(<1.0.2)都是不支持ALPN的;
2)nginx 需要 >= 1.9.5,但據說在nginx 1.9.15 ~ 1.10.x有POST bug,然后在1.11.0才修復了這個BUG(詳情請參閱:https://imququ.com/post/nginx-http2-post-bug.html)
三、讓網站支持HTTP/2:
好的,上面一和二說明了服務端與客戶端的要求,只要滿足了這些要求,就可以順利搭建http2的服務;
1、升級服務端:
1)升級OpenSSL
下載openssl 1.1.0(https://www.openssl.org/source/openssl-1.1.0c.tar.gz)
解壓:
[root@static-mwrhc ~]# tar -zvxf openssl-1.1.0c.tar.gz
安裝:
[root@static-mwrhc ~]# cd openssl-1.1.0c
[root@static-mwrhc openssl-1.1.0c]# ./config shared zlib
[root@static-mwrhc openssl-1.1.0c]# make
[root@static-mwrhc openssl-1.1.0c]# make install
備份原有的openssl:
[root@static-mwrhc openssl-1.1.0c]# mv /usr/bin/openssl /usr/bin/openssl.back
[root@static-mwrhc openssl-1.1.0c]# mv /usr/include/openssl /usr/include/openssl.back
建立軟鏈:
[root@static-mwrhc openssl-1.1.0c]# ln -s /usr/local/bin/openssl /usr/bin/openssl
[root@static-mwrhc openssl-1.1.0c]# ln -s /usr/local/include/openssl /usr/include/openssl
配置動態連接庫:
[root@static-mwrhc openssl-1.1.0c]# echo "/usr/local/lib64/" >> /etc/ld.so.conf
[root@static-mwrhc openssl-1.1.0c]# ldconfig
升級完成,查看openssl版本:
[root@static-mwrhc openssl-1.1.0c]# openssl version
OpenSSL 1.1.0c 10 Nov 2016
2)安裝新版Nginx
安裝pcre的devel依賴包:
[root@static-mwrhc nginx-1.13.9]# yum -y install zlib zlib-devel openssl openssl--devel pcre pcre-devel
下載 nginx-1.13.9.tar.gz(http://nginx.org/download/nginx-1.13.9.tar.gz)並解壓:
[root@static-mwrhc ~]# tar -zvxf nginx-1.13.9.tar.gz
編繹:
[root@static-mwrhc ~]# cd nginx-1.13.9
[root@static-mwrhc nginx-1.13.9]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_flv_module --with-http_gzip_static_module --with-pcre --with-stream --with-openssl=/root/openssl-1.1.0c【openssl的源碼路徑】
[root@static-mwrhc nginx-1.13.9]# make
如果出現以下錯誤:
cc: /root/openssl-1.1.0c/lib/libssl.a: No such file or directory
cc: /root/openssl-1.1.0c/lib/libcrypto.a: No such file or directory
make[1]: *** [objs/nginx] Error 1
make[1]: Leaving directory `/root/nginx-1.13.9'
make: *** [build] Error 2
則:
[root@static-mwrhc nginx-1.13.9]# ln -s /usr/local/lib64/libssl.a /root/openssl-1.1.0c/lib/libssl.a
[root@static-mwrhc nginx-1.13.9]# ln -s /usr/local/lib64/libcrypto.a /root/openssl-1.1.0c/lib/libcrypto.a
然后再次執行:
[root@static-mwrhc nginx-1.13.9]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_flv_module --with-http_gzip_static_module --with-pcre --with-stream --with-openssl=/root/openssl-1.1.0c【openssl的源碼路徑】
[root@static-mwrhc nginx-1.13.9]# make
安裝:
[root@static-mwrhc nginx-1.13.9]# make install
安裝完成,查看安裝信息:
[root@static-mwrhc nginx-1.13.9]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.13.9
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
built with OpenSSL 1.1.0c 10 Nov 2016
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_flv_module --with-http_gzip_static_module --with-pcre --with-stream --with-openssl=/root/openssl-1.1.0c
3)配置Nginx
server {
listen 443 ssl http2;
server_name h2.static.com;
root /apps/dat/web/working/h2.static.com;
index index.html;
#SSL配置
ssl on;
ssl_certificate /usr/local/nginx/conf.d/server.crt;
ssl_certificate_key /usr/local/nginx/conf.d/server.key;
}
2、訪問站點(成功):
四、前端調試工具:
1、新版chrome支持HTTP/2,如果想做啟動HTTP2的前后對比,可以退出chrome瀏覽器后,使用如下命令啟動Chrome,就可以禁用http2,這樣就會自動降級成HTTP/1.1:
以mac為例,使用命令行工具,找到chrome的安裝位置,然后:/Applications/Google Chrome.app/Contents/MacOS/Google Chrome --disable-http2
2、抓包:
目前feddler不支持http2,使用feddler進行抓包,瀏覽器會自動降級為http1.1
而charles支持http2