前端學Serverless系列-性能調優
作者簡介:
龍永霞,騰訊高級前端開發工程師。目前在在線教育負責企鵝輔導業務的開發工作。對前端性能優化,全棧開發有濃厚的興趣。
Serverless雲函數的優點是支持高並發,理論上無限自動擴容,但也有其自身的缺點,如冷啟動特性導致冷啟動的時延比較高。那麼實際上性能如何,是否還有性能優化的空間和手段呢?
最近試點Serverless的一個項目是從原有的node服務遷移到騰訊雲函數Serverless的。既然是項目遷移,那麼就要對比一下遷移前後的性能了。
壓測方案
從測試同事那很快就找到壓測大師這個工具,壓測大師配置和報告都還算比較完善,是騰訊出的。
缺點是:發請求的時間間隔有限制,最大只能隔1分鐘,那就無法純測試雲函數的冷啟動了,不過每個階段都有自動增加人數,也能間接測試到冷啟動到性能,看到測試結果時不時飆升到高耗時,那就多數就是冷啟動的耗時。
壓測大師鏈接:https://wetest.qq.com
如果測200以內的並發人數,可以直接測試。如果需要測高於200人數的並發量,需要先進行域名驗證(具體可以看壓測大師提示並操作即可),就是放一個key到你的域名根目錄下,可以讓壓測大師可以訪問到。
這就帶來了新難題,因為騰訊雲自動生成的api網關鏈接下必然會有http://yourdomain/release/這個環境的路徑,根本無法將key放到根目錄下。
騰訊雲也提供了一個路徑映射的功能,可以將這個/release/的路徑去掉,但是這個功能綁定在了自定義域名中,就是說,首先你得有一個自己的域名。
和騰訊雲的產品反饋這個問題之後,產品同學將這個需求加到了排期中。
我暫時從同事那借用了一個子域名,繼續將測試工作進行下去。
注意:需要在騰訊雲備案了的域名。可以綁定一個子域名,在個人的域名管理界面中,通過cname指向騰訊雲的API網關域名即可。
如果你要支持https的話,還需要申請個證書。有免費的可以申請,同一個主域名可以申請20個。申請完成之後,將證書上傳到騰訊雲即可。
如果不需要https,直接選http就可以了,準備工作都OK了。
評測及優化
選擇測試的CGI,初步是要比較兩者的鏈路,所以選取一個簡單的邏輯,只有一個資料庫查詢的CGI,壓力從低到高進行嘗試。
剛嘗試到200並發人數到時候,成功率就有點不對勁了,只有80%多?
分析問題
後來查了一下雲函數的日誌,問題就比較明了了。
雖然說是理論上可以無限擴容,但是也要配置給不給這個上限。
將耗時比較長的部分和雲函數開發一起分析,發現耗時主要集中在:
1.函數調用:代碼本身執行時間為70ms~115ms左右,路徑耗時從5ms~600ms不等。
2.熱啟動:也就是代碼本身執行的時間,這個主要是邏輯和需要調用第三方應用的耗時。這個壓測例子的耗時就會在50ms之內,20ms左右。騰訊雲同學反饋啟動性能很快就有大的改善。
3.現在有一些大於5s的,那些耗時都在路徑上或者有可能在單節點處理能力上。具體消耗在哪裡暫時看不出來。
優化方案
進行了代碼的優化,實際上耗時最大的請求的確有所改善,但是平均值和90%的值還是被一些高耗時拉高。
但是實際上壓測大師測的結果依然沒有達到很理想,下面匯總一下截止目前階段的結果。
進一步分析
理論上雲函數服務該做的優化都做了,而且理論表現應該不會這麼差?
後來騰訊雲的同事用python寫了腳本來自己壓測,發現200並發的平均耗時在200ms之內,而且超過200ms的請求也在可數之內。
由於兩個測試的結果不一致,從自己寫的腳本和wetest壓測方案兩方展開分析。
a.腳本盡量去還原wetest的方案,如異地部署,階梯增加並發,並且每個階段維持30s。
b.直接找到了wetest的後台同事進行問題溝通,嘗試了長連接、短連接、多IP壓力源、去掉日誌列印等操作。
結果:這個壓測結果其實已經達到了我們預設的優化目標,平均在200ms之內。
以下還是wetest的壓測結果(短連接 多IP)。
其中還有一個很有意思的結果,長連接下的壓測結果:
那麼到底是什麼原因導致了這個結果的差異呢?
答案為:「網路連接耗時」。
在這個例子中,將長連接改成短連接,從一地壓測改成多IP壓測,效果最為明顯,去掉日誌列印也一定程度減少了壓測源的性能損耗。
用戶側對比評測
既然地域不同,網路不同,耗時差異這麼大,那麼真實的用戶耗時到底如何呢?
紅色的是Serverless,黃色的是原來的NodeServer。
分析問題
1、針對Serverless做了優化:將非簡單請求改成簡單請求,減少一次「預檢」請求,加上dns-prefetch,並加上了NodeServer原來的請求耗時進行對比。
剛開始是因為設置了header頭,瀏覽器認為這個是非簡單請求。
非簡單請求的CORS請求,會在正式通信之前,增加一次HTTP查詢請求,稱為"預檢"請求(preflight)。瀏覽器先詢問伺服器,當前網頁所在的域名是否在伺服器的許可名單之中,以及可以使用哪些HTTP動詞和頭信息欄位。只有得到肯定答覆,瀏覽器才會發出正式的XMLHttpRequest請求,否則就報錯。更詳細可以查閱跨域資源共享 CORS 詳解:http://www.ruanyifeng.com/blog/2016/04/cors.html
圖為一個請求產生了兩個請求,第一個是預檢請求,其中method為OPTION, 返回狀態碼是204。
如果要用到非簡單請求的時候,服務端響應CORS的設置要注意到:
如果單選具體的GET,POST,可以在API網關中的API管理中設置是否支持CORS,如果需要支持多個的請求方法的話,就只能後端業務處理。
2、優化之後,發現Serverless的請求依然比NodeServer慢100ms左右。
繼續分析發現:Serverless的請求會比NodeServer請求多一個Initial connection和SSL的時間。
為什麼NodeServer沒有呢,因為測試的頁面和發請求的頁面是同域的,所以這部分時間省了。為什麼之前Serverless沒有發現呢,因為socket連接之後沒有那麼快銷毀,在頁面重複刷新的時候,反而看不到這個耗時。
需清理一下socket: chrome://net-internals/#sockets
就可以復現了,那麼這個耗時差距的原因就很明顯了。
我做了一個簡單頁面進行測試,發現這樣的結果。Serverless和NodeServer的全程耗時其實差不太多,但是TCP連接和SSL時間會長很多。
這是為什麼呢?因為測試的這個Serverless是部署在上海的,而我是在深圳進行測試的。
之後再做了一個測試,加了一個部署在廣州的雲函數。
結果很明顯。
異地訪問部署的問題,因為原有的NodeServer接入了STGW。
STGW全稱Secure Tencent Gateway,騰訊安全雲網關,是一套實現多網統一接入,支持自動負載均衡的系統。由於STGW提供了就近接入和SSL加速,所以這兩部分時間都相應有不少的優化。
那麼Serverless能不能用多地部署,就近接入來解決這個問題呢。
目前Serverless的雲函數和API網關都是地域隔離的。也就是說廣州的API網關對應廣州的雲函數,不能一個網關對多個地域的雲函數。這個需求和騰訊雲的產品溝通之後,也納入到了以後的規劃建設當中。
那麼我們目前有沒有折中的方案呢?
我們設想了一些中轉的方案:
最後我們選擇了最右側的方案,主要是簡單。
而且還可以繼續通過在header中設置preconnect減少TCP握手和SSL的時間。
preconnect的兼容性情況:
使用之前:
使用了之後的效果:
可以看到Initial connection 和 SSL的時間是可以直接節省掉了,在網路差的情況下,這部分節省的時間更為顯著。
小結
Serverless雲函數性能評測和優化結果:
在API網關監控到到耗時(不包括網路時間和握手時間)
目前騰訊雲Serverless雲函數的響應性能已經達到了需要即時返回場景的可用狀態,期待未來更優秀的性能。
1、壓測方案、問題分析
1)wetest是騰訊公司支持的通用壓測方案,要用好也要對裡面提供的設置了解清楚用法和用途。
2)測試不限於壓測工具,本地腳本、瀏覽器network分析、線上用戶test等等都可以嘗試用來評測分析。
2、性能優化方案
期待雲方面的優化:
允許客戶設置並發上限
冷啟動、熱啟動、實例保留策略的優化
架構升級(測試中)
就近接入(待規劃)
代碼方面的優化:
代碼邏輯和第三方調用
拆分不常用功能,減少代碼量
使用預載入減少connect的時間(preconnect)
接入STGW進行轉發
寫在最後
1、雲函數在國內處於高速發展階段,應用的過程中還會遇到各種問題,不過騰訊雲的同事們積極響應,主動和我們一起尋找問題解決問題,最終一起共同成長。
2、雲函數目前的特點不適合有狀態的應用,但是這個不是必然的,這個問題有了合適的方案之後,就不會再是問題。
本文轉載自:ServerlessCloudNative
活動推薦
6月2日
武漢世貿希爾頓酒店 漢陽廳
雲 社區邀您參加雲 開發者大會(武漢站)
一起漫談數據平台與智能應用
洞察數據,啟迪智能
TAG:雲加社區 |