前端抱怨API響應(yīng)慢,怎么辦?
來(lái)源:juejin.cn/post/6936063402640932878
分析API的耗時(shí)是將API的總耗時(shí)拆分為不同的部分,清晰的知道是什么原因?qū)е潞臅r(shí)過(guò)高。我們借助不同的工具,在不同的網(wǎng)絡(luò)環(huán)境下進(jìn)行耗時(shí)分析,從而提出相應(yīng)的優(yōu)化建議。
請(qǐng)求發(fā)送過(guò)慢導(dǎo)致耗時(shí)增加;
DNS解析過(guò)慢導(dǎo)致耗時(shí)增加;
惡劣的網(wǎng)絡(luò)環(huán)境導(dǎo)致耗時(shí)增加;
一直在排隊(duì)導(dǎo)致響應(yīng)過(guò)慢;
服務(wù)端響應(yīng)過(guò)慢導(dǎo)致耗時(shí)增加;
響應(yīng)體積過(guò)大導(dǎo)致耗時(shí)增加;
等等……
一般從感官上覺得API接口響應(yīng)慢,大部分人會(huì)直接歸結(jié)于服務(wù)端處理慢,其實(shí)是不合理的。通過(guò)在內(nèi)網(wǎng)環(huán)境下的API耗時(shí)分析和外網(wǎng)環(huán)境下的API耗時(shí)分析的對(duì)比,一般會(huì)認(rèn)識(shí)到原因所在。
通過(guò)瀏覽器的開發(fā)者工具分析

重點(diǎn)關(guān)注指標(biāo)Waiting (TTFB),TTFB代表第一個(gè)字節(jié)到達(dá)的時(shí)間。此時(shí)間包括一次往返延遲和服務(wù)器準(zhǔn)備響應(yīng)所花費(fèi)的時(shí)間。可以近似的認(rèn)為是服務(wù)端耗時(shí)。
如果網(wǎng)絡(luò)情況不好或者響應(yīng)數(shù)據(jù)過(guò)大,則Content Download耗時(shí)會(huì)長(zhǎng)一些,這時(shí)候應(yīng)該考慮壓縮響應(yīng).
Timing
開發(fā)者工具中Network中顯示了當(dāng)前頁(yè)中調(diào)用的網(wǎng)絡(luò)資源,點(diǎn)擊資源可以查看資源的詳情,其中Timing是資源調(diào)用時(shí)的耗時(shí)情況。
Queueing. 【排隊(duì)中】瀏覽器在以下情況下將請(qǐng)求排隊(duì):有更高優(yōu)先級(jí)的請(qǐng)求. 已為該來(lái)源打開了六個(gè) TCP連接,這是限制。僅適用于HTTP/1.0和HTTP/1.1.瀏覽器正在磁盤緩存中短暫分配空間. Stalled. 【停滯】該請(qǐng)求可能由于排隊(duì)中描述的任何原因而停止.Proxy negotiation. 【代理協(xié)商】瀏覽器正在與代理服務(wù)器協(xié)商請(qǐng)求.Request sent. 【發(fā)送請(qǐng)求】該請(qǐng)求正在發(fā)送.Waiting (TTFB). 【等待中】瀏覽器正在等待響應(yīng)的第一個(gè)字節(jié)。TTFB代表第一個(gè)字節(jié)到達(dá)的時(shí)間。此時(shí)間包括一次往返延遲和服務(wù)器準(zhǔn)備響應(yīng)所花費(fèi)的時(shí)間.Content Download. 【響應(yīng)內(nèi)容下載】瀏覽器正在接收響應(yīng).
其他可能出現(xiàn)的
DNS Lookup. 【DNS】瀏覽器正在解析請(qǐng)求的IP地址.Initial connection. 【初始化連接】瀏覽器正在建立連接,包括TCP握手/重試和協(xié)商SSL.
通過(guò)httpstat工具分析
httpstat git地址:
https://github.com/reorx/httpstat
如果是在Linux服務(wù)器上進(jìn)行調(diào)用,則可以使用httpstat。
安裝
直接下載腳本
wget?https://raw.githubusercontent.com/reorx/httpstat/master/httpstat.py
通過(guò)pip
pip?install?httpstat
Mac
brew?install?httpstat
使用
httpstat可以使用cURL的參數(shù)。
httpstat?www.baidu.com?httpstat?127.0.0.1/post?-X?POST?--data-urlencode?"id=1"?-v?

Server Processing可以近似的認(rèn)為是服務(wù)端耗時(shí)。
服務(wù)端到底慢在哪里?
打印耗時(shí)日志?
StopWatch?stopWatch?=?new?StopWatch();
stopWatch.start();
//?...
stopWatch.stop();
LOGGER.info("[某某某業(yè)務(wù)]?-?[Time:{}ms]",?stopWatch.getLastTaskTimeMillis());
腦子瞬間一熱就會(huì)使用的方法,簡(jiǎn)單直接,但是如果定位不準(zhǔn)確,你可能要加很多這種日志。
還是用火焰圖吧
讓軟件執(zhí)行情況可視化,是性能分析、調(diào)試的利器
火焰圖的生成工具很多,比如Async Profiler、linux-perl,網(wǎng)上也有很多關(guān)于這方面的介紹,IDEA也集成Async Profiler,這個(gè)很方便。
IntelliJ IDEA中的火焰圖
打開火焰圖
如果沒有開啟,則點(diǎn)擊+號(hào),進(jìn)行添加。

選擇程序進(jìn)行火焰圖的分析
可以選擇一個(gè)已經(jīng)運(yùn)行中的java程序進(jìn)行分析,輸出火焰圖。

直接使用Async Profiler更簡(jiǎn)單
async-profiler git地址[1]
安裝
從git上直接下載。

解壓下可用。
簡(jiǎn)單使用
執(zhí)行命令。
./profiler.sh?-d?10?-f?/tmp/flamegraph.svg?
./profiler.sh?-e?itimer?-d?10?-f?/tmp/flamegraph.svg?
可以通過(guò)-e來(lái)指定cpu、alloc、lock、wall、itimer、ClassName.methodName。
cpu:在這種模式下,profiler收集堆棧跟蹤樣本,包括Java方法、本機(jī)調(diào)用、JVM代碼和內(nèi)核函數(shù)。alloc:可以將探查器配置為收集分配最大堆內(nèi)存的調(diào)用站點(diǎn),而不是檢測(cè)消耗CPU的代碼。即檢查當(dāng)前分配內(nèi)存最多的地方。lock:滿足的鎖定嘗試,包括Java對(duì)象監(jiān)視器和可重入鎖。wall:告訴async-profiler在給定的時(shí)間內(nèi)對(duì)所有線程平均采樣,而不管線程狀態(tài)如何: 運(yùn)行、休眠或阻塞。例如,在分析應(yīng)用程序啟動(dòng)時(shí)間時(shí),這可能會(huì)有所幫助。。ClassName.methodName:ClassName.methodName選項(xiàng)使用給定的Java方法,以便使用堆棧跟蹤記錄此方法的所有調(diào)用。cpu:在這種模式下,profiler收集堆棧跟蹤樣本,包括Java方法、本機(jī)調(diào)用、JVM代碼和內(nèi)核函數(shù)。

在瀏覽器中打開file:///tmp/flamegraph.svg,并找到調(diào)用的API,我這里調(diào)用的是ProjectManageController中的findProject方法。

根據(jù)長(zhǎng)度可以看出該方法中調(diào)用方法的耗時(shí)情況,這樣我們就知道耗時(shí)主要集中在什么地方。
PS:如果方法名被編譯掉了,那么可以在java啟動(dòng)時(shí)加入-XX:+PreserveFramePointer
做更多的工作
用戶體驗(yàn)的優(yōu)化是一個(gè)長(zhǎng)期而艱巨的過(guò)程,為了衡量我們網(wǎng)站的性能是否良好,我們有更多的工作需要去做。通常,會(huì)在底層自定義一些以用戶為中心的指標(biāo),比如Server-Timing[2]。
參考資料
https://github.com/jvm-profiling-tools/async-profiler: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fjvm-profiling-tools%2Fasync-profiler
[2]https://w3c.github.io/server-timing/: https://link.juejin.cn?target=https%3A%2F%2Fw3c.github.io%2Fserver-timing%2F
程序汪資料鏈接
程序汪接的7個(gè)私活都在這里,經(jīng)驗(yàn)整理
Java項(xiàng)目分享 最新整理全集,找項(xiàng)目不累啦 06版
堪稱神級(jí)的Spring Boot手冊(cè),從基礎(chǔ)入門到實(shí)戰(zhàn)進(jìn)階
臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開放下載!
臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開放下載!
字節(jié)跳動(dòng)總結(jié)的設(shè)計(jì)模式 PDF 火了,完整版開放下載!
歡迎添加程序汪個(gè)人微信 itwang009? 進(jìn)粉絲群或圍觀朋友圈
