《如何使用火焰圖來分析服務(wù)器負(fù)載》要點:
本文介紹了如何使用火焰圖來分析服務(wù)器負(fù)載,希望對您有用。如果有疑問,可以聯(lián)系我們。
LucidChart 提供在線編輯流程圖、網(wǎng)絡(luò)拓?fù)鋱D、ER 圖、 UML 圖以及腦圖等多種圖表服務(wù),有超過 7 百萬的用戶,因其簡單直觀的交互體驗和強大的多人協(xié)作功能,是可以替代 Visio 的最佳選擇.
在 Lucid,我們使用面向服務(wù)的架構(gòu)來建設(shè)我們的系統(tǒng).其中字體服務(wù)(font service)就是其中之一,它負(fù)責(zé)根據(jù)字體族名稱和 unicode 編碼范圍來提供相應(yīng)的字體服務(wù),同時也對用戶上傳的字體進(jìn)行校驗和檢查.在生產(chǎn)環(huán)境中,該服務(wù)的負(fù)載一直很高,這一點超出我們的預(yù)期(使用或等待 CPU 的平均線程數(shù)).特別從去年開始,我們注意到字體服務(wù)的負(fù)載高的驚人,特別是在晚上這樣的流量低峰時期.
幸運的是最終我們找到了根本原因,并通過改進(jìn)大大提高了服務(wù)的整體性能和穩(wěn)定性.通過下面的內(nèi)容,您將了解到我們是如何做到的.
圖1: 字體服務(wù)在變更前后服務(wù)器平均負(fù)載對比
我們從 Netflix 找到了一個非常棒的火焰圖工具,并部署到生產(chǎn)環(huán)境. 此工具可以將多個不同調(diào)試分析工具的數(shù)據(jù)組合在一起并生成火焰圖,以可視化的方式展示服務(wù)器和 JVM 的資源使用情況.
如下圖所示,每個矩形表示一個棧幀,同時矩形的寬度代表了資源(比如 CPU 時間)的使用情況,Y 軸表示調(diào)用棧.通過識別那些寬的矩形塊,就能快速縮小問題范圍.在調(diào)試和排查字體服務(wù)時,它極大地幫助了我們.
圖2: 高負(fù)載時字體服務(wù)中一臺服務(wù)器的火焰圖
在高負(fù)載狀態(tài)下,我們對字體服務(wù)收集數(shù)據(jù)并生成了幾個火焰圖.下圖是其中之一,并且特別展示了 JVM 相關(guān)棧的部分.可以分析得出,大部分時間都花在了 libz.so
這一步(gzip 使用該庫進(jìn)行壓縮/解壓縮操作),剩下大部分時間都花在了 XML 轉(zhuǎn)義和 UTF-8 編碼上.
圖3: JVM 相關(guān)棧活動的局部火焰圖
首先多啰嗦幾句這個字體服務(wù)的一些背景情況.我們將所有字體相關(guān)數(shù)據(jù)存儲在 Amazon S3 中,具體來說是將每個字體的每個 unicode 范圍分別存為一個 S3 object
.當(dāng)其他服務(wù)請求為了獲取字體族,一組 unicode 范圍,或者是用戶自定義字體時會向字體服務(wù)請求字體數(shù)據(jù),接著字體服務(wù)將字體數(shù)據(jù)包裹在 XML 中返回.
功能非常簡單,并沒有什么明顯的密集型計算.但是對于出現(xiàn)的高負(fù)載問題,火焰圖幫助我們識別出了問題所在—— libz
,XML 轉(zhuǎn)義和 UTF-8編碼都使用了大量的 CPU.
但是為什么會產(chǎn)生這么多編碼和壓縮的消耗?記得前面提到晚上時間的負(fù)載反而是最高的嗎?我們的晚上(美國山區(qū)時間)正好是亞洲地區(qū)的白天,該地區(qū)很多用戶都使用中文、日文或韓文等亞洲語言.會進(jìn)行大量的 gzip 解壓縮 → UTF-8解碼 → XML 轉(zhuǎn)義 → UTF-8編碼 → gzip 壓縮.相比于拉丁語系,單個 CJK 的 unicode 范圍比拉丁語系的 unicode 范圍大2個數(shù)量級(1MB:60KB).所以上述的轉(zhuǎn)換過程都壓到了 CPU 上,特別壓縮和解壓縮,以及 XML 轉(zhuǎn)義這類操作.
字體服務(wù)對請求的響應(yīng)本質(zhì)上只是 S3 上原始數(shù)據(jù)的集合.它確實需要執(zhí)行一些重要的附加任務(wù),如權(quán)限檢查和從字體族中檢索名稱.但是,字體服務(wù)根本沒必要擋在 S3 前面來代理那些字體數(shù)據(jù)!所以解決辦法很簡單, 直接用包含 S3 object 的鏈接(就是那些字體數(shù)據(jù))的列表作為響應(yīng)返回,字體服務(wù)不再從 S3 下載并重新編碼字體數(shù)據(jù).所以從圖1中可以看出負(fù)載幾乎降低到可忽略的程度.
通過調(diào)試分析生產(chǎn)環(huán)境,我們能夠找到并消除那些不必要的任務(wù)和工作,進(jìn)而降低服務(wù)器負(fù)載.
[1] Brendan D. Gregg的個人網(wǎng)站 http://www.brendangregg.com
[2] Flame graphs http://www.brendangregg.com/flamegraphs.html
[3] 白話火焰圖 https://huoding.com/2016/08/18/531
[4] Java Flame graphs http://www.brendangregg.com/blog/2014-06-12/java-flame-graphs.html
[5] OpenRestry 關(guān)于火焰圖在 Lua 中的使用?https://moonbingbing.gitbooks.io/openresty-best-practices/flame_graph.html
[6] 在 Netflix 中的應(yīng)用 http://techblog.netflix.com/2015/07/java-in-flames.html
[7] 在 Netflix 中的應(yīng)用 http://techblog.netflix.com/2016/04/saving-13-million-computational-minutes.html
原文來自微信公眾號:高可用架構(gòu)
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/2713.html