Fundebug網(wǎng)站升級HTTP/2猎贴,真的變快了班缎!

作為新一代的HTTP協(xié)議蝴光,HTTP/2可以提高網(wǎng)站性能,優(yōu)化用戶體驗达址,Fundebug也是時候升級HTTP/2了蔑祟,雖然已經(jīng)有點晚了。

升級HTTP/2是一件很簡單的事情沉唠,改1行Nginx配置就好了做瞪,但是,工程師只知道How是遠(yuǎn)遠(yuǎn)不夠的右冻,還需要理解Why装蓬,這就要求我們需要足夠的事先調(diào)研(1. 什么是HTTP/2?)以及事后分析(4. 升級HTTP/2真的提高性能了嗎纱扭?)牍帚。

1. 什么是HTTP/2?

HTTP/2是新一代的HTTP協(xié)議乳蛾,于2015正式發(fā)布暗赶。

與其他眾多Web技術(shù)標(biāo)準(zhǔn)一樣,推動HTTP/2標(biāo)準(zhǔn)的依然是Google肃叶。發(fā)布Chrome的時候Google說過要推動Web技術(shù)的發(fā)展蹂随,然后它真的做到了。(JavaScript深入淺出第5課:Chrome是如何成功的因惭?

根據(jù)W3Techs的統(tǒng)計岳锁,截止2019年10月26日,全世界41.3%的網(wǎng)站已經(jīng)使用了HTTP/2蹦魔。

根據(jù)Can I use激率,絕大多數(shù)瀏覽器都支持了HTTP/2:

HTTP/2主要有以下幾個特性:

  • HTTP/2為二進(jìn)制協(xié)議


圖片來源:Valentin V. Bartenev

由上圖可知,HTTP/1.1傳輸?shù)氖俏谋緮?shù)據(jù)勿决,而HTTP/2傳輸?shù)氖嵌M(jìn)制數(shù)據(jù)乒躺,提高了數(shù)據(jù)傳輸效率。

  • HTTP/2支持TCP連接多路復(fù)用


圖片來源:Factory.hr

由上圖可知低缩,HTTP 1.1需要為不同的HTTP請求建立單獨的TCP連接嘉冒,而HTTP/2的多個HTTP請求可以復(fù)用同一個TCP連接。

要知道咆繁,建立TCP連接時需要3次握手讳推,再加上TLS的4次握手,加起來就是7次握手么介,如果可以復(fù)用TCP連接的話娜遵,則可以減少這些多余的開銷蜕衡。

  • HTTP/2會壓縮請求Header


圖片來源:運維實談

如上圖所示壤短,第2個請求的Header只有:path不一樣设拟,因此壓縮空間非常可觀久脯。

Headers壓縮的算法HPACK本身似乎很復(fù)雜(其實也不難)纳胧,但是算法思想其實非常簡單的,假設(shè)我們在瀏覽器發(fā)起100個請求帘撰,它們的user-agent是不會變的跑慕,那我們?yōu)槭裁葱枰貜?fù)傳輸這個長長的字符串呢?用dictionary記錄一次不就行了摧找!

  • HTTP/2支持服務(wù)器推送(Server Push)

圖片來源:lujjjh

由上圖可知核行,當(dāng)客服端向服務(wù)端請求HTML時,Server Push服務(wù)端可以提前返回HTML所依賴的css蹬耘、js等資源芝雪,這樣可以節(jié)省解析HTML以及請求資源的時間,從而縮短頁面的加載時間综苔。

2. 如何升級HTTP/2惩系?

我們使用了Nginx作為前端頁面與后端接口的反向代理服務(wù)器(Reverse Proxy),只需要修改一下Nginx配置文件就可以升級HTTP/2了如筛,非常簡單堡牡。

注意,在 Nginx 上 開啟 HTTP/2 需要 Nginx 1.9.5 以上版本(包括1.9.5)杨刨,并且需要 OpenSSL 1.0.2 以上版本(包括1.0.2)晤柄。使用nginx -V命令可以查看Nginx的版本信息:

nginx -V
nginx version: nginx/1.12.1
built by gcc 6.3.0 20170516 (Debian 6.3.0-18)
built with OpenSSL 1.1.0f  25 May 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin3-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.12.1/debian/debuild-base/nginx-1.12.1=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'

可知,我們使用的Nginx版本為1.12.1妖胀,OpenSSL版本為1.1.0f可免,符合要求。

還有一點做粤,雖然HTTP/2標(biāo)準(zhǔn)并沒有要求加密浇借,但是所有瀏覽器都要求HTTP/2必須加密,這樣的話怕品,只有HTTPS才能升級HTTP/2妇垢。

如果你還沒用過HTTPS的話,不妨看看我的博客:教你快速擼一個免費HTTPS證書肉康,其實也很簡單闯估。

一切前提沒問題的話(Nginx>=1.9.5,OpenSSL>=1.0.2吼和,HTTPS)涨薪,只需要修改1行配置,在listen指令后面添加http2:

server
{
    listen 443 ssl http2;
    server_name www.fundebug.com;
}

重啟Nginx炫乓,升級HTTP/2就成功了刚夺,可以使用curl命令檢查:

curl -sI https://www.fundebug.com
HTTP/2 200
server: nginx/1.12.1
date: Mon, 07 Oct 2019 00:12:53 GMT
content-type: text/html; charset=UTF-8
content-length: 4892
x-powered-by: Express
accept-ranges: bytes
cache-control: public, max-age=0
last-modified: Sun, 06 Oct 2019 23:07:25 GMT
etag: W/"131c-16da353dbc8"
vary: Accept-Encoding
strict-transport-security: max-age=15768001

3. HTTP/2導(dǎo)致Safari瀏覽器OPTIONS請求失敗

升級HTTP/2之后献丑,使用Safari的用戶發(fā)現(xiàn)無法登陸Fundebug了:

我們的前端異常監(jiān)控插件捕獲了這個報錯:

可知,是/api/members/login接口出錯了侠姑。

經(jīng)過排查發(fā)現(xiàn)是OPTIONS請求失敗了:

curl -X OPTIONS https://api.fundebug.com/api/members/login -v
*   Trying 120.77.45.162...
* TCP_NODELAY set
* Connected to api.fundebug.com (120.77.45.162) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=api.fundebug.com
*  start date: Sep 15 16:38:43 2019 GMT
*  expire date: Dec 14 16:38:43 2019 GMT
*  subjectAltName: host "api.fundebug.com" matched cert's "api.fundebug.com"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fcfbb80ce00)
> OPTIONS /api/members/login HTTP/2
> Host: api.fundebug.com
> User-Agent: curl/7.54.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
* http2 error: Invalid HTTP header field was received: frame type: 1, stream: 1, name: [content-length], value: [0]
* HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, Client hello (1):
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

根據(jù)curl的報錯信息创橄,可知是Header中content-length有問題:

* http2 error: Invalid HTTP header field was received: frame type: 1, stream: 1, name: [content-length], value: [0]

將Nginx配置文件中OPTIONS請求的Content-Length配置注釋掉,問題就解決了:

if ($request_method = "OPTIONS")
{
    add_header Access-Control-Allow-Origin *;
    add_header 'Access-Control-Max-Age' 86400;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, OPTIONS, DELETE';
    add_header 'Access-Control-Allow-Headers' 'token, reqid, nid, host, x-real-ip, x-forwarded-ip, event-type, event-id, accept, content-type';
    # add_header 'Content-Length' 0; // 必須注釋莽红,否則HTTP/2會報錯
    add_header 'Content-Type' 'text/plain, charset=utf-8';
    return 200;
}

HTTP/2中對于Header有特殊處理妥畏,這應(yīng)該是導(dǎo)致出錯的根本原因,關(guān)于這一個問題安吁,我會在下一篇博客中詳細(xì)介紹醉蚁。

4. 升級HTTP/2真的提高性能了嗎?

理論上來說鬼店,HTTP/2應(yīng)該可以提高網(wǎng)站性能馍管,但是實際情況是怎樣呢?HTTP/2真的可以提高性能了嗎薪韩?如果有的話确沸,究竟提高了多少呢?

于是俘陷,我使用Chrome記錄了升級HTTP/2前后Fundebug首頁的加載時間罗捎,計算了5次加載的平均時間(單位為妙),如下表:

HTTP版本 DOMContentLoaded Load Finish
HTTP/1.1 1.572 4.342 5.138
HTTP/2 1.0004 4.102 4.288

可知拉盾,HTTP/2明顯提高了首頁加載時間桨菜,DOMContentLoaded、Load與Finish時間均有明顯提高捉偏。

一共也就改了2行Nginx配置倒得,就可以提高頁面訪問性能,多好柏睬荨霞掺!

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市讹躯,隨后出現(xiàn)的幾起案子菩彬,更是在濱河造成了極大的恐慌,老刑警劉巖潮梯,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骗灶,死亡現(xiàn)場離奇詭異,居然都是意外死亡秉馏,警方通過查閱死者的電腦和手機耙旦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萝究,“玉大人免都,你說我怎么就攤上這事锉罐。” “怎么了琴昆?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵氓鄙,是天一觀的道長馆揉。 經(jīng)常有香客問我业舍,道長,這世上最難降的妖魔是什么升酣? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任舷暮,我火速辦了婚禮,結(jié)果婚禮上噩茄,老公的妹妹穿的比我還像新娘下面。我一直安慰自己,他們只是感情好绩聘,可當(dāng)我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布沥割。 她就那樣靜靜地躺著,像睡著了一般凿菩。 火紅的嫁衣襯著肌膚如雪机杜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天衅谷,我揣著相機與錄音椒拗,去河邊找鬼。 笑死获黔,一個胖子當(dāng)著我的面吹牛蚀苛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播玷氏,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼堵未,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盏触?” 一聲冷哼從身側(cè)響起兴溜,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耻陕,沒想到半個月后拙徽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡诗宣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年膘怕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片召庞。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡岛心,死狀恐怖来破,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情忘古,我是刑警寧澤徘禁,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站髓堪,受9級特大地震影響送朱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜干旁,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一驶沼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧争群,春花似錦回怜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至轻要,卻和暖如春复旬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背伦腐。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工赢底, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人柏蘑。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓幸冻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親咳焚。 傳聞我的和親對象是個殘疾皇子洽损,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,047評論 2 355