由于一次功能上線後,導緻某資料量急劇下滑,給我們緊張的呢!排查過程也是個學習過程!抛開結果,方法論可供參考~
1. 确認問題的真實性?
被資料部門告知,某資料量下滑嚴重,當時即知道問題的嚴重性。且該問題是在我的功能上線後産生,第一反應就是,我代碼哪裡寫錯了? 但是,還得按流程來,通過各種次元資料對比請求量,實際落地量。确認問題!
其實該過程中,我們并沒有确認自己的資料量下滑。但是這也脫不了資料下滑的幹系。隻能進行下一步!
2. 檢查代碼,找有經驗的同學,對比原有功能差異點?
這個步驟其實,是有點盲目的感覺。因為第一步的排查并沒有找到足夠的證明說明問題出在我們,但是問題在于期間隻有我們上過線,是以隻能自我檢討了。
不過幸好,這過程還真有用,果真發現了自己埋的一個坑,此坑确實會導緻該資料量的下滑。趕緊修掉呗!
然後松了一口氣,以為搞好了。其實不然,資料量依然上不去。這就尴尬了!
我已經開始懷疑人生,難道代碼沒發上去?難道線上和本地某個地方不一樣?測試環境反複測試正确無誤。我真想直接把測試環境代碼弄到線上去,哎,算了吧,很多東西是不會以人的意志為轉移的,咱們還是理性點!别謀出路吧!
3. 直接坐到dba旁邊去吧,讓我們随時關注資料量?
自我排查已經救不了自己了,那就上dba那裡。麻煩幫我統計下上線後,資料量的變化,結果是沒多大差别。心想有可能是時間太短,看不出變化,等會兒再統計吧。依然沒有變化!我的神呐,定了鍋還在。
大的資料量不行,那我用自己的賬号來測試吧,操作完成後,觀察資料,發現有時有有時無!額,說不出啥了。
4. 本地調試吧?
原本以為,是線上問題,緊急處理下就好了。然而事實卻超出了我的預料,将驗證直接交給線上,是對使用者的不負責,是對資料的不負責。咱們還是從本地做起吧。
本地調試要走vpn,有點煩,但不管怎麼樣,還是跑起來了。沒問題啊!這尴尬了。
然後,引出下一個議題!
5. 線上環境配置與測試環境不一樣?
然後我們努力找出其中的不同點,哪怕是多了一個檔案,某個檔案的更改時間點不一緻,我們都想去試一下!當然了,為了穩妥起見,我們還是不能直接線上上驗證的,除非有足夠的證據說明線上的配置是有問題的。當然我們最終并沒有找到這樣的證據,隻是将線上的所有東西都搬到測試環境來驗證,結果是暢通無阻!
還有一個證明此路不通的理由,之前的配置跑得好好的東西,難道會自己壞掉?不可能吧。此路不通!
6. 實在不行了,隻能改代碼線上調試?
調試第一步,各自打日志!把之前請求列印不全的地方,加上完整日志,再發一版吧!有了日志,就有證據,但是真的是急中生錯啊,日志居然打得不對,将參數列印為了記憶體位址也真是夠了。
日志改好後,測試呗,繼續用自己的賬号。還是一樣,有時能能進有時不能(監控手段為dba起一個臨時的kafka消費者,然後将資料拉出來看)!那咋整呢?
難道是有的機器壞了?配置設定到壞的機器上去的請求就失敗,配置設定到正确機器的上去的請求就正确。然後吭哧吭哧搞了半天的資料驗證,曾經以為這是方向,結果又被打回。
7. 不行咱們就抓包吧?
tcpdump,一個網絡流抓包神器,lsof助攻一下。
抓包隻是為了确認一個問題,客戶機器有發送請求到服務端機器,網絡流正常運轉!然後證明,用戶端機器有大量長連接配接到伺服器,資料流發送接收正常(syn)。這至少說明了一點,用戶端是沒有問題的!那麼就還剩一個問題,那就是服務端出問題了!我們堅信,當然要有證據嘛。
同理,我們在服務端機器上進行反向抓包,然後抓到了來自用戶端的包,很流暢嘛!額。。。
8. 不行,沒有思路了,重新開機機器吧?
不,我說的是重新開機服務。最近不是有改動嘛,按理誰改動重新開機誰。然而這是沒有用的,因為之前的幾次釋出早已重新開機了n次。那咋整呢。隻剩重新開機服務端,kafka服務了呗,死馬當活馬醫吧!
重新開機後,驗證呗。結果貌似還是發現有成功,有失敗!
9. 改異步請求為同步請求?
又沒思路了,我不甘心呐,為啥測試環境好好的,到線上就不行了呢?再想想差别在哪裡?
得出的結論是,線上并發大,測試環境量無。然後發現這一塊代碼是由異步線程做的,會不會是這裡有問題?
不管了,改成同步請求試試吧。再來一版!
别說,改為同步後,雖然使用者請求基本都慢死了,但是發現kafka請求确實存在了。難道真的是因為這個,那我們也不能這麼改啊,使用者體驗是第一位的,為了這事改異步為同步,咱得吃不了兜着走啊。改回來繼續其他的吧!
10. 再回測試環境,壓測并發?
改還原為異步後,又回到當初有成功有失敗境地了。
既然懷疑線上高并發導緻,那為什麼不在測試環境高并發壓測一下呢?用shell腳本快速寫了一個循環請求腳本,大量請求到kafka後,并無一絲異常,到此并發問題取消。(for,nohup a.sh > /dev/null 2&>1 &)n 次即模拟n個并發請求
11. 再來細細檢查代碼吧?
都不知道查了幾遍了,但是還是要查啊,不然咋整呢,幾個人一起看代碼呗!
然而這并沒有什麼卵用。
12. 抛開使用者行為,直接以指令行形式操作請求?
雖然使用者行為是最真實的驗證,但是也是比較麻煩的驗證。
我們就抛開各種中間環節,直接向kafka伺服器發起請求!
分兩種方式,1 用現在的代碼去請求,2 用kafka自帶的請求方式請求。結果得到兩個不同的結果,用代碼的方式請求的資料,沒有成功,用kafka自己的請求方式,則毫秒級響應。哎,這是讓我又懷疑代碼?
13. 已走投無路,讓我們再看一眼資料吧?
真的是沒有思路了,隻能再來看看資料,當打發時間了。
意外就在你想不到的時候發生了。資料已經恢複正常了!我擦!
倒推時間,倒推事件,是由于kafka重新開機,導緻資料回升的。
好吧,問題已經定位,kafka卡頓導緻。咱們已經熬不住了,發個結論郵件,就先回去洗洗睡吧!
14. 為什麼kafka會卡頓?
這才是問題的根本!隻是我們當時已經沒有力氣再往下搞了!
結論是由于topic請求量過大,而partition過小,導緻吞吐量下降。将partition改大之後,終于真正恢複正常!
額,好像做了很多無用功,沒辦法 !
不要害怕今日的苦,你要相信明天,更苦!