記一次線上OOM和效能優化

2021-09-24 06:43:45 字數 1605 閱讀 9088

某次周五,發布前一周的伺服器小動盪?

上周五,通過grafana監控,線上環境突然出現cpu和記憶體飆公升的情況:

既然伺服器在某個時間點出現了高負荷,於是就先去找一開始出現問題的伺服器,去找耗時的服務,例如我當時去找資料庫耗時的服務,由於上週的日誌已經被刷掉,於是我大致描述一下:

[admin@*** ***yyyy]$ grep '15:14:' common-dal-digest.log |  grep -e '[0-9]ms'

複製**

上述語句是查詢在15:14那一分鐘內,在common-dal-digest.log檔案中,耗時超過1000ms的sql服務(我上週查的是耗時超過10秒的服務)。

通過traceid去查nginx儲存的訪問日誌,定位在該時間點內,分發到該伺服器上的使用者請求。還有根據該traceid,定位到整個呼叫流程所使用到的服務,發現的確十分耗時...

於是拿到了該請求具體資訊,包括使用者的登入手機號碼,因為這個時候,其它幾台伺服器也出現了cpu和記憶體負載公升高,於是根據手機號查詢了其它幾台伺服器的訪問日誌,發現同乙個請求,該使用者也呼叫了很多次...

通過mat工具對dump檔案進行分析,調查是什麼請求占用了大記憶體:

觀察了該物件的引用樹,右鍵選擇【class_ reference】,檢視物件列表,和觀察gc日誌,定位到具體的物件資訊。

通過日誌以及dump檔案,都指向了某個檔案匯出介面,接著在**中分析該介面具體呼叫鏈路,發現匯出的資料很多,而且老**進行計算的邏輯巢狀了很多for迴圈,計算效率低。

查詢了該使用者在這個介面的所呼叫的資料量,需要查詢三個表,然後for迴圈中大概會計算個100w+次,導致阻塞了其它請求,線上的伺服器cpu和記憶體使用情況一直飆公升。

在看到該業務在git提交記錄是我上一年實習期寫的時候,我的內心是崩潰的,當時對業務不熟悉,直接迴圈呼叫了老**,而且也沒有測試過這麼大的資料量,所以gg了。

然後我就開始做**效能優化,首先仔細梳理了一下整個業務流程,通過增加sql查詢條件,減少資料庫io和查詢資料量,優化判斷條件,減少for巢狀、迴圈次數和計算量。

對比新老**所占用的cpu和記憶體狀態

優化前:

優化後:

通過上述優化之後,計算1w條資料量進行匯出,在老**需要48s,新**也要8s

,不過這是大資料量的情況下,實際使用者的資料沒有這麼多,所以基本上滿足了線上99%的使用者使用。

當然,由於這些資料是本地開發環境新增加的,與出現oom問題的使用者資料量還有些差別,但通過優化後的**,已經在資料庫查詢的時候就過濾掉很多無效的資料,在for迴圈計算前也加了過濾條件,所以真正計算起來起來就降低了很多計算量。

恩,自己優化好了,還要等測試爸爸們測試後才敢上線,這次要瘋狂造資料

在開發一開始的時候,都沒有考慮到效能問題,想著滿足需求就完成任務,但資料量一大起來,就有可能出現這些oom問題,所以以後開發時,需要考慮一下幾點:

果然每次看之前寫的**,都有種要si要si的感覺

萬元預算玩新機 還有沈大媽的表情真好玩,直接拿來用了~

記一次線上OOM問題

首先是 jmap dump format b,file file.hprof 匯入mat工具 定位的問題是 standardmanager和standardsession檢視原始碼發現concurrenthashmap node就是standardmanager的session屬性 protecte...

一次線上oom問題記錄

某天早上發現服務無法正常訪問,於是展開問題排查。1。首先檢視日誌,發現有oom日誌存在。這時候看到oom,犯了想當然的錯誤,認為是記憶體不足,堆記憶體空間已經用完。於是檢視 發現某個模組中有如下 誰寫的,站出來,我保證不打你。當時盲目的認為就是使用這個執行緒池的問題 關於此執行緒池的弊端不再贅述 於...

記一次前端效能優化

公司新做的乙個專案,寫完 第一次上測試環境測試,首屏載入要6秒左右的樣子,於是進行了一系列的優化,成功將首屏時間降到了200ms左右 今天寫篇文章,分享一下這次優化心得。專案背景 vue cli 2.x框架 一 技巧 二 壓縮 三 cdn 一 技巧 去掉多餘 減少請求數量 復用元件 二 壓縮 開啟w...