Qzone 高效能 HTTPS 實踐

2022-06-05 21:06:09 字數 3913 閱讀 8888

自從去年qq空間移動端頁面開始切換到https之後,頁面效能遇到了比較大的挑戰,https對頁面訪問速度帶來了比較大的影響,所以我們通過實踐總結了一些能夠提公升https頁面訪問速度的方法,這些資料都是我們和stgw的同事反覆實驗、多次分析所得到的,希望能夠減少大家對於全站啟用https的顧慮。我們的目的是,在不影響使用者體驗的情況下,竭盡全力保護使用者的資訊保安!

頁面在切到https之前,ios的訪問速度約為1795ms,切到https之後,ios的訪問速度直接飆到2630ms,我的天吶,**了900ms,接近50%,嚇得我趕緊把入口又切回了http。之後,便開始踏上了提公升https訪問速度的道路。(文章裡的資料以ios為例,訪問速度指的是頁面html開始請求到頁面js執行完畢的耗時)。先簡單以圖示總結下我們優化的結論:

使用spdy協議是我們優化的第一步,spdy(speedy)是google很早就提出的協議,通過多路復用、請求優先順序以及http報頭壓縮,來提公升頁面的訪問速度。但是公司貌似沒有乙個統一的平台支援spdy,在尋求了teg小夥伴的幫助之後,他們首次支援了spdy。spdy在ios的相容性比較好,ios 8.0以上的safari和webview都支援,覆蓋了qzone 85%以上的ios使用者。所以決定開啟https+spdy試試效果。開啟spdy之後的頁面訪問速度提公升了370ms,已經非常不錯了。(在spdy的相容性上,ios大部分都支援了,而安卓tbs核心支援spdy的版本也正在灰度當中,全量之後預計也能覆蓋80%的qzone使用者。)

根據第一次spdy的嘗試,https的訪問速度有了300多毫秒的提公升,但跟http相比差距還是有400ms的差距,分析了一下,這400ms的差距主要是來自於ssl握手的耗時,根據spdy協議,每個網域名稱建立乙個tcp連線,各自要進行一次ssl握手,每次耗時約200ms,頁面一共有兩個關鍵網域名稱,所以https+spdy一共比http慢了400ms。根據這個分析結果,我們也有了進一步的優化方向,那就是減少ssl的耗時。

減少ssl握手的耗時,可以有三個方式:

(1)提公升tcp連線的復用率;

(2)提公升ssl session的復用率;

(3)減少頁面上的網域名稱。

對於提公升tcp連線的復用率,我們想了乙個方法,在頁面的入口處預建了乙個連線,在使用者點選入口之前,先向h5.qzone.qq.com(頁面的網域名稱)發起乙個https請求,可以請求乙個返回內容為空的url。同時,伺服器端要開啟keep alive, keep alive的時間也並不是越長越好,我們使用的是60秒。這個預建的連線,不止減少了ssl握手的耗時,實際上同時也節省了tcp建立連線的時間。根據我們的實踐資料,在預建連線之後,頁面的訪問速度又提公升了400ms。其中,tcp連線復用的命中率大約是75%。

對於提公升ssl session 復用率,需要伺服器端支援session ticket或者session cache,目前我們的stgw是支援了分布式session cache和全域性session ticket key。需要說明一下的是,如果我們前面做了預建連線,復用了tcp連線的請求不會再發生ssl握手,也就不需要session復用。不過還是分享下我們ssl session復用的實踐資料。ssl session復用對大部分安卓使用者的提公升非常明顯,可以把ssl握手耗時從之前的400ms優化到100多ms。而對於ios,由於本身機器效能更好,ssl 握手時間的耗時本身就比安卓使用者少,從之前的200ms優化到100ms,提公升了50%,並且ios由於不支援session ticket,只能使用session cache,復用率比較低。ssl seesion總體的復用率大約是40%。

對於減少頁面上的網域名稱,前面說到頁面有兩個關鍵網域名稱,乙個是h5.qzone.qq.com,乙個是cdn網域名稱qzonestyle.gtimg.cn。每個網域名稱的ssl握手各多耗時200ms,所以另乙個優化的方式就是網域名稱收歸,把頁面收歸到只有乙個網域名稱,減少一次ssl握手的耗時。於是我們把頁面上qzonestyle.gtimg.cn的js通過**的方式也收歸到h5.qzone.qq.com,使這個頁面只有乙個關鍵網域名稱,而h5.qzone.qq.com在入口頁面已經做了預建連線,最大程度減少了tcp和ssl的時間。網域名稱收歸後,頁面的訪問速度提公升了200ms。這種**收歸的方式,也有另乙個好處,qzone由於業務複雜,網域名稱非常多,通過中間層**收歸網域名稱,再**到各個業務,這樣切換https對各個業務都是透明的,可以說大大降低了我們全站切換到https的開發成本。

推薦使用的tls協議和cipher suite,在協議和演算法層面,我們也做了一些統計來進行對比。在https握手過程中記錄協議型別、加密套件、握手時間,並且將上述內容返回給頁面。頁面在記錄使用者的訪問速度之後,上報資料的同時,把上述的協議型別等資料也一同上報。

從上表可以看出來,tls1.2協議的效能要明顯優於1.1和1.0。cipher suite 方面,ecdhe-rsa-aes128-gcm-sha256和ecdhe-rsa-aes128-sha256效能最好。ecdhe-rsa-chacha20-poly1305理論上講對效能提公升有較大幫助,但是由於ios不支援該類演算法,所以從資料樣本上無法體現優勢。除了上面所列出來的,後續我們依然會進行協議和演算法層面的更多效能分析和優化,包括tcp引數調優,握手過程優化,ssl record size適配等。

做了以上這些優化之後,https的頁面訪問速度提公升了1000+ms,相比http,差距已經非常小了。由於tcp復用,甚至比之前的訪問速度還要快。同時,我們還在馬不停蹄地做更多的嘗試,比如開始寫這篇文章的時候還在用spdy,寫到結尾的時候我們已經啟用了http/2(喂,難道不是因為作者是拖延症患者嗎?!)親,你還有什麼理由再不啟用https?

下面,我們來看一下如何測試https頁面優化結果

1) 點選進入壓測大師產品首頁( )開通專案,建立測試,點選進入url測試。名稱和描述可以自己填寫。(圖中示例起始人數50人,每隔60秒增加50人,加到200人為上限)

輸入合適的測試標題和測試設定(此圖為**,橫屏**效果更佳)

2)新建乙個客戶端請求,介面壓測包括讀寫介面,讀介面基本是get請求,寫介面基本是post請求。get請求使用url請求引數,填寫測試用例的基礎數值,選擇正確的url

配置頁面header資訊

3) 隨後進行header的配置,header的名稱在選定url的內,開啟url的鏈結(推薦使用chrome瀏覽器),敲擊f12並重新整理頁面,選定network-name-headers-request headers(header的名稱與值均在內檢視,如下圖所示)

檢視頁面header資訊

到這裡,基本就完成了對https的配置過程了,是不是很簡單?下面**可以再回顧一下操作的流程:

gif動態圖展示操作的流程(此圖為**,橫屏**效果更佳)

wetest壓測大師運用了沉澱十多年的內部實踐經驗總結,通過基於真實業務場景和使用者行為進行壓力測試,幫助遊戲開發者發現伺服器端的效能瓶頸,進行針對性的效能調優,降低伺服器採購和維護成本,提高使用者留存和轉化率。

功能目前免費對外開放中,點選 即可體驗!

高效能Nginx最佳實踐

三,nginx配置location 配置塊 server 詳情 location會嘗試根據使用者請求中的uri來匹配location的uri表示式,如果可以匹配,就選擇location塊中的配置來處理使用者請求。示例 四,nginx常規配置 一 定義環境變數 語法 evn var var value...

高效能快取實踐 快取穿透

問題快取穿透 大量的客戶端請求,引數都是無效的,導致直接穿過快取,直接查詢資料庫。需要將這些無效的請求引數,過濾,不直接查詢資料庫,減少資料庫的壓力。提供正常請求的響應率。解決方法 對於非法引數請求,通過前端後端的引數校驗,直接阻斷請求。使用spring boot cache 預設是快取null結果...

高效能mysql(一) 建立高效能索引

單列索引和多列索引 單列索引 多個單列索引的選擇問題 多個or條件 多個單列的效能往往效能很低,盡量建立高效的多列索引。多列索引 選擇合適的索引順序 避免範圍條件 在where子句中,in是有效的,範圍條件會導致後面的索引無效!在order by中,範圍條件和in都會導致無法按照索引排序!按照索引順...