1.問題現(xiàn)象
- 16:55 發(fā)生告警
- 16:57 發(fā)現(xiàn)服務有3臺實例重啟
- 16:58 節(jié)點重啟完成,功能接口恢復正常
2.結(jié)論
安全組攻防調(diào)用了管理后臺舊接口论熙,由于舊接口是提供給管理后臺使用福青,參數(shù)校驗不夠充分,攻防組調(diào)用接口時未傳參數(shù)赴肚,導致查詢沒有條件素跺,把全表2多千萬數(shù)據(jù)到內(nèi)存中,
發(fā)生內(nèi)存溢出誉券,然后服務一直gc,cpu達到100%刊愚,觸發(fā)容器在長時間高cpu重啟的機制
3.排查過程
1踊跟、發(fā)生重啟以及cpu 100%告警后,立馬查看監(jiān)控,發(fā)現(xiàn)只有3臺節(jié)點cpu接近100%商玫,同時gc的次數(shù)很高箕憾,由于不是所有節(jié)點的彪高,說明不是大流量這類的請求過來拳昌,我們的排查方向就
大致定位是:定時任務袭异、某些請求導致觸發(fā)了特殊邏輯導致內(nèi)存一直占用不釋放
CPU:
內(nèi)存:
2、查看運維給出的Moss數(shù)據(jù)炬藤,我們仔細看了一下后御铃,發(fā)現(xiàn)這里給出的內(nèi)存和cpu的指標都是正常的,并無問題沈矿,
再看時間點上真,發(fā)現(xiàn)16:57分的時候,其實服務cpu已經(jīng)是開始下降的差不多了羹膳,導致這個時間抓出來的線程和內(nèi)存指標不是沒有出現(xiàn)問題的現(xiàn)場睡互,只能繼續(xù)找別的線索
3、接下來我們排查是不是有定時任務導致的陵像,我們把時間線拉長就珠,并未發(fā)現(xiàn)有周期性的cpu、內(nèi)存占用很高的問題醒颖,所以暫時往別的方向排查妻怎。
4、開始排查云日志图贸,找耗時長的請求蹂季,但是這個時間點雖然挺多耗時長的請求,但不確定就是引起問題的請求疏日,這里花了不少時間偿洁,但是因為這個時間點服務處理很慢了,任何請求都有可能變慢沟优,同時請求太多涕滋,有些慢也不一定會導致這個cpu高、內(nèi)存高問題
5挠阁、考慮到內(nèi)存一直漲宾肺,在gc,那有可能一直在查數(shù)據(jù)侵俗,那么查數(shù)據(jù)可能會導致redis或者數(shù)據(jù)庫相關(guān)的中間件cpu或者其他指標波動锨用。帶著這個思路我們發(fā)現(xiàn)那3臺機器的下行帶寬很大,那就大致吻合了這個猜想隘谣,說明節(jié)點一直在查什么數(shù)據(jù)增拥。
6、既然帶寬這么大,那么就開始看redis或者數(shù)據(jù)庫有沒有什么異常掌栅,因為一般這些數(shù)據(jù)的來源都是周邊的中間件秩仆,同時這么大流量也有可能會導致一些指標異常,我們就需要找出這些異常的點猾封,然后反推出我們的容器在做什么操作澄耍。
redis:
這里看redis很正常,然后繼續(xù)查看mycat也是正常的
7晌缘、查看mysql齐莲,這個時候我們發(fā)現(xiàn)在那個點數(shù)據(jù)庫的cpu很高,同時上行帶寬也相對較大
8枚钓、找DBA幫忙拉出那個時間段的慢sql情況铅搓,發(fā)現(xiàn)問題了,有3條sql全表查搀捷,這張表又有2千萬多數(shù)據(jù)星掰。
9、通過這條sql嫩舟,我們定位出了代碼位置氢烘。會產(chǎn)生上面的sql肯定是由于if里面的條件都是false導致的
10.通過日志我們找到了調(diào)用的請求,時間點和請求路徑以及重啟的節(jié)點家厌,都是對得上播玖,至此問題就找了,就是由于這3個請求導致全表查數(shù)據(jù)饭于,oom了
11蜀踏、通過看操作日志的人,發(fā)現(xiàn)是安全組調(diào)用的掰吕,繞開了我們的前端正常邏輯果覆,直接調(diào)用的接口,沒有任何傳參殖熟,導致sql變成了全表掃描局待。