2016ArchSummit-https 性能優(yōu)化

該分享主要兩部分:
1.分析https的性能瓶頸點(diǎn) 2.根據(jù)瓶頸點(diǎn)的優(yōu)化方案

性能分析

https比起http的缺點(diǎn)主要是慢和貴,慢主要體現(xiàn)在未經(jīng)過(guò)任何優(yōu)化的https比http要慢幾百毫秒,在移動(dòng)端,甚至有500毫秒以上。貴主要體現(xiàn)在計(jì)算性能和服務(wù)器成本,服務(wù)端需要不斷做加解密操作。https比http多了一層tls協(xié)議,因此這些性能問(wèn)題也主要是tls的問(wèn)題。關(guān)務(wù)tls的握手過(guò)程和加解密過(guò)程,可以參考阮一峰的博客,筆者看過(guò)覺(jué)得通俗易懂,更能便于理解tls的性能優(yōu)化點(diǎn)。
1.關(guān)于ssl握手過(guò)程
http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html
2.關(guān)于數(shù)字簽名
http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html
3.關(guān)于RSA原理
http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html
po出演講中的兩張圖(圖片來(lái)自演講ppt)便于理解:

https握手過(guò)程.png
https中的計(jì)算環(huán)節(jié).png

由上圖中,我們可以看到https中主要有四個(gè)計(jì)算環(huán)節(jié),證書(shū)校驗(yàn)、非對(duì)稱密鑰交換、對(duì)稱加解密和完整性校驗(yàn)。證書(shū)校驗(yàn)保證雙方的身份的合法性,非對(duì)稱秘鑰交換主要用來(lái)生成保密數(shù)據(jù)的對(duì)稱秘鑰,完整性主要保證數(shù)據(jù)的完整性,不被篡改。

從上圖的握手耗時(shí),我們可以看到在ECDHE_RSA 非對(duì)稱密鑰交換握手中,其中ServerKeyExchange過(guò)程,耗時(shí)2.4毫秒,在演講者的性能試驗(yàn)中,CPU的一核每秒只能處理400多次。這里補(bǔ)充一下這個(gè)過(guò)程耗時(shí)嚴(yán)重的原因,ServerKeyExchange過(guò)程其實(shí)就是使用DH算法中,服務(wù)端使用RSA算法的私鑰對(duì)DH參數(shù)做數(shù)字簽名,這個(gè)過(guò)程因?yàn)槭褂梅?wù)端的私鑰加密,私鑰的位數(shù)一般是遠(yuǎn)大于公鑰的,因?yàn)橛?jì)算復(fù)雜度很高,就會(huì)非常耗時(shí)。同樣在通用的RSA非對(duì)稱秘鑰中,服務(wù)端同樣會(huì)因?yàn)樾枰褂盟借€去解密客戶端傳來(lái)pre-master key,因而同樣會(huì)存在耗時(shí)嚴(yán)重的問(wèn)題。

對(duì)于握手耗時(shí),演講者也給出了其他計(jì)算過(guò)程的耗時(shí)實(shí)驗(yàn)統(tǒng)計(jì)。如下圖

其他計(jì)算性能.png

上圖統(tǒng)計(jì)可以看出性能最好的是AES-128-GCM,性能最差的是AES-256-CBC,但即使它性能最差,它也只需要47微秒就能處理4000個(gè)字節(jié),性能相比來(lái)說(shuō)也還能接受。

根據(jù)上面的統(tǒng)計(jì)可以看出,非對(duì)稱密鑰交換過(guò)程的耗時(shí)占據(jù)了整體耗時(shí)75%左右,而對(duì)稱加密對(duì)性能影響較小。

優(yōu)化方案

簡(jiǎn)化握手過(guò)程

方式一:使用Session ID。Session ID由服務(wù)器生成并返回給客戶端,客戶端再次發(fā)起SSL握手時(shí)會(huì)攜帶上Session ID,服務(wù)端拿到后會(huì)從自己的內(nèi)存查找,如果找到便意味著客戶端之前已經(jīng)發(fā)生過(guò)完全握手,是可以信任的,然后可以直接進(jìn)行簡(jiǎn)化握手。
缺點(diǎn):在使用Nginx時(shí),只支持單機(jī)多進(jìn)程間共享的Session Cache。假如接入用的是一臺(tái)服務(wù)器、一臺(tái)Nginx的話,那ID生成和查找都在一起,肯定是可以命中的,但是大部分特別是流量比較大的接入環(huán)境都是多臺(tái)機(jī)器接入,那么當(dāng)用戶隔了較長(zhǎng)時(shí)間后攜帶Session ID發(fā)起https請(qǐng)求時(shí),可能落到了其他機(jī)器上而找不到之前服務(wù)器保存的Session ID,導(dǎo)致請(qǐng)求失敗。

方式二:使用分布式Session Cache,服務(wù)端會(huì)將Session ID寫(xiě)入全局緩存中,比如redis緩存,這樣用戶下次發(fā)起握手時(shí),可以直接從全局的緩存中查找到Session ID,提高成功率。可以參考的開(kāi)源庫(kù):OpenResty,BoringSSL
缺點(diǎn):消耗大量緩存。

同時(shí)上述兩種方式中,都需要對(duì)openssl做改造,因?yàn)镺penSSL提供了一個(gè)Session Cache的callback可以回調(diào),但是這個(gè)回調(diào)函數(shù)是同步的。這會(huì)拖累整體服務(wù)性能。BoringSSL中實(shí)現(xiàn)了Session Cache的異步查找,可以參考。

方式三:使用Session Ticket,Session Ticket由服務(wù)端加密分發(fā)給用戶,只要服務(wù)端的機(jī)器都使用相同的秘鑰,就可以保證簡(jiǎn)化握手的成功率。
缺點(diǎn):服務(wù)端需要做解密,影響性能。

Session Ticket,Session ID和Session Cache都有一個(gè)共同點(diǎn),都是基于內(nèi)存的,但當(dāng)客戶端重啟,瀏覽器tab關(guān)閉后又打開(kāi)時(shí),會(huì)導(dǎo)致Session數(shù)據(jù)丟失,所以可以采用如下方式:對(duì)于安全系數(shù)要求不是很高的業(yè)務(wù)可以控制Session數(shù)據(jù)存儲(chǔ)在App的私有路徑中,并且有秘鑰開(kāi)關(guān)隨時(shí)關(guān)閉這個(gè)功能。

異步代理耗時(shí)計(jì)算

雖然簡(jiǎn)化握手能提高很多性能,但完全握手在總的握手比例中仍然很高,有30%。所以對(duì)完全握手可以把耗時(shí)算法分離出來(lái)交給計(jì)算集群去計(jì)算,這個(gè)過(guò)程是異步的,不需要同步等待計(jì)算結(jié)果返回。即將耗時(shí)圖中ServerKeyExchange過(guò)程(設(shè)計(jì)到私鑰加解密的過(guò)程)異步化。

工程實(shí)現(xiàn):Nginx需要改造(這部分沒(méi)怎么看懂,后面去了解下Nginx的工作流程)。對(duì)OpenSSL改造,需要對(duì)OpenSSL的協(xié)議棧進(jìn)行修改,主要涉及到s3_srvr.c這個(gè)文件。OpenSSL1.1.0已經(jīng)支持異步事件。

寫(xiě)在最后

我司使用的私有協(xié)議和tls協(xié)議中,tls的性能明顯不如私有協(xié)議,目前服務(wù)端對(duì)tls應(yīng)該還沒(méi)有做優(yōu)化,可以考慮使用這個(gè)分享中異步代理的方式來(lái)提高tls的處理性能。畢竟有不少客戶會(huì)切到tls協(xié)議做請(qǐng)求的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容