Spring Boot Serverless 實(shí)戰(zhàn)系列 | 性能調(diào)優(yōu)

點(diǎn)擊上方藍(lán)字關(guān)注我們

我將通過一系列文章,從架構(gòu),部署,監(jiān)控、性能、安全等 5 個方面來分析 Serverless 平臺運(yùn)行 Spring Boot 應(yīng)用的優(yōu)劣。為了讓分析更有代表性,我選擇了 Github 上 star 數(shù)超過 50k 的電商應(yīng)用 mall?作為示例。這是系列文章的第四篇, 本文向大家展示如何對 Serverless 應(yīng)用進(jìn)行性能調(diào)優(yōu)。
實(shí)例啟動速度優(yōu)化
在之前的文章實(shí)戰(zhàn)教程中,相信大家都感受到 Serverless 的便捷之美,只需上傳代碼包和鏡像就能夠輕松上線一個彈性高可用的 Web 應(yīng)用。
但是它仍存在首次啟動“冷啟動延時”的問題,Mall 應(yīng)用實(shí)例的啟動大約 30 秒左右,用戶會感受較長時間的冷啟動延時,在這個“即時時代”應(yīng)用程序響應(yīng)慢多少會有些瑕不掩瑜。(“冷啟動”是指函數(shù)服務(wù)于特定調(diào)用請求時的狀態(tài),當(dāng)一段時間沒有請求后,Serverless 平臺則會回收函數(shù)實(shí)例;等到下一次再有請求時,系統(tǒng)會再次實(shí)時拉起實(shí)例,該過程稱之為冷啟動。)

對 mall-admin 服務(wù)發(fā)起請求,成功后查看 FC 控制臺,我們能夠看到相應(yīng)的請求信息。注意關(guān)閉“僅查看函數(shù)錯誤”,這樣才會顯示所有請求。指標(biāo)監(jiān)控和調(diào)用鏈路數(shù)據(jù)收集會存在一定延時,如果沒有顯示,請等待一會再刷新。找到冷啟動標(biāo)記的請求,點(diǎn)擊 “更多” 下的 “請求詳情”。

調(diào)用鏈路會顯示冷啟動各個環(huán)節(jié)的耗時。冷啟動包含以下幾個環(huán)節(jié):
代碼準(zhǔn)備(PrepareCode):主要是下載代碼包或者鏡像。由于我們已經(jīng)啟用了鏡像加速功能,不需要下載全部的鏡像,因此這一步的延時非常短。
運(yùn)行時初始化(RuntimeInitialization):從啟動函數(shù)開始,到函數(shù)計算(FC)系統(tǒng)探測到應(yīng)用端口就緒為止。這中間包含了應(yīng)用啟動時間。在命令行執(zhí)行 s mall-admin logs 查看相應(yīng)的日志時間,我們也能看到 Spring Boot 應(yīng)用的啟動需要花大量的時間。
應(yīng)用初始化(Initialization):函數(shù)計算提供了 Initializer 接口,用戶可以將一些初始化邏輯放在 Initializer 中執(zhí)行。
調(diào)用延時(Invocation):處理請求的延時,這個延時非常短。

從上述鏈路追蹤圖來看,實(shí)例啟動時間是瓶頸,但是我們可以采取多種方式來優(yōu)化。
1、使用預(yù)留實(shí)例
Java 類應(yīng)用普遍會啟動較慢。應(yīng)用在初始化時,也需要和很多外部服務(wù)交互,耗時較長。這類流程是業(yè)務(wù)邏輯需要的,很難優(yōu)化延時。因此函數(shù)計算提供了預(yù)留實(shí)例功能。預(yù)留實(shí)例的起停由用戶自己控制,沒有請求也會常駐在那,因此不會有冷啟動的問題,當(dāng)然用戶需要為整個實(shí)例的運(yùn)行付費(fèi),即便實(shí)例沒有處理任何請求。



2、優(yōu)化實(shí)例啟動速度
延遲初始化
在 Spring Boot 2.2 及更高版本中,可以開啟一個全局延遲初始化標(biāo)志。這將提高啟動速度,但代價是第一個請求的延遲時間可能變長,因?yàn)樾枰却M件首次初始化。
SPRING_MAIN_LAZY_INITIATIALIZATION=true關(guān)閉優(yōu)化編譯器
JAVA_TOOL_OPTIONS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1"s.yaml 中設(shè)置環(huán)境變量示例:

登錄實(shí)例檢查環(huán)境變量是否配置正確:

在實(shí)例詳情頁中點(diǎn)擊“登錄實(shí)例”。

注意:對于非預(yù)留實(shí)例,一段時間沒有請求后,函數(shù)計算系統(tǒng)會自動回收實(shí)例。此時無法再登入實(shí)例(上面的實(shí)例詳情頁面中的登錄實(shí)例按鈕會變灰)。所以請執(zhí)行調(diào)用后,在實(shí)例被回收之前盡快登錄。

配置合理的實(shí)例參數(shù)
注意:請區(qū)分實(shí)例并發(fā)度和 QPS 的區(qū)別。
系統(tǒng)能夠迅速統(tǒng)計實(shí)例并發(fā)度指標(biāo)值進(jìn)行擴(kuò)縮容。CPU/Memory/Network/Load 等實(shí)例級別的指標(biāo)通常是后臺統(tǒng)計,需要花費(fèi)數(shù)十秒的指標(biāo)統(tǒng)計后才能進(jìn)行伸縮,難以滿足在線應(yīng)用的彈性伸縮要求。
在各種條件下,實(shí)例并發(fā)度指標(biāo)都能夠穩(wěn)定的反映系統(tǒng)負(fù)載高低。如果以請求延時作為指標(biāo),系統(tǒng)難以區(qū)分是實(shí)例過載導(dǎo)致延時變大,還是下游服務(wù)成為瓶頸導(dǎo)致延時變大。例如一個典型的 Web 應(yīng)用,通常會訪問 MySQL 數(shù)據(jù)庫。如果數(shù)據(jù)庫成為瓶頸,請求延時變大,此時擴(kuò)容不但毫無意義,而且會壓垮數(shù)據(jù)庫,讓情況更加惡化。QPS 和請求延時相關(guān),也會有上述問題。
實(shí)例并發(fā)度作為伸縮依據(jù)雖然有上述優(yōu)點(diǎn),但用戶常常并不知道該設(shè)置多大的實(shí)例并發(fā)度。我推薦按照下述流程確定合理的并發(fā)度:
將應(yīng)用函數(shù)的最大實(shí)例數(shù)設(shè)置為 1,確保壓測到單個實(shí)例的性能。 使用負(fù)載壓測工具對應(yīng)用進(jìn)行壓測,查看 tps 和請求延時等指標(biāo)。
逐步調(diào)大實(shí)例并發(fā)度,如果性能仍然良好,則繼續(xù)調(diào)大;如果性能不符合預(yù)期,則調(diào)小并發(fā)度。
文中網(wǎng)址匯總(可滑動)
Spring Boot:https://spring.io/projects/spring-bootMall:https://github.com/macrozheng/mallServerless Devs 安裝文檔:http://serverlessdevs.com/zhcn/docs/installed/cliinstall.html函數(shù)計算:https://www.aliyun.com/product/fc


獎勵看到最后的你
:
# 點(diǎn)個在看,并在下方留言互動
# 然后,將截圖發(fā)送至后臺,試試手氣?
# 本周互動獎品是“阿里云定制數(shù)據(jù)線”
# 本期禮品開獎時間1月25日?

