溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

nodejs問題是怎么樣排查的

發(fā)布時間:2021-12-13 17:43:34 來源:億速云 閱讀:162 作者:柒染 欄目:大數(shù)據(jù)

nodejs問題是怎么樣排查的,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

相信大家都遇到過Error: read ECONNRESET這個錯誤。雖然通過ECONNRESET錯誤碼我們很容易查到這個錯誤意味著什么,但是通過源碼和分析工具進行一次徹底的分析,會讓你更加了解這個錯誤的產(chǎn)生和原理。更讓人神清氣爽。
下面分為兩個部分,首先通過nodejs源碼分析這個錯誤產(chǎn)生的原因,然后通過網(wǎng)絡工具抓包的方式捕獲這個錯誤。
1 源碼分析
我們從建立一個tcp連接成功后,nodejs執(zhí)行的操作開始分析(net.js)。

nodejs問題是怎么樣排查的  

這是連接成功后執(zhí)行的nodejs回調(diào)?;卣{(diào)里執(zhí)行了新建一個socket表示和客戶端通信的對象。我們看new Socket做了什么事情。  
 
nodejs問題是怎么樣排查的  

new Socket的主要邏輯有  
1 保存和客戶端通信的handle(socket)  
2 注冊讀回調(diào)  
3 注冊讀事件  
我們先看第三點  
 
nodejs問題是怎么樣排查的  

socket是可讀可寫的流,read(0)直接調(diào)用可讀流的函數(shù),可讀流提供了抽象的邏輯,具體的讀取操作由子類實現(xiàn)(實現(xiàn)_read函數(shù),可讀取的read會調(diào)用_read函數(shù))。我們看一下Socket類_read函數(shù)的實現(xiàn)。  
 
nodejs問題是怎么樣排查的  

直接調(diào)用handle的readStart函數(shù)。因為我們這里使用的是tcp服務。所以handle對應的實現(xiàn)在tcp_wrap.cc里。但是我們發(fā)現(xiàn)tcp_wrap.cc沒有readStart函數(shù)。一路往父類找,最終在stream_wrap.cc找到了該函數(shù)。  
 
nodejs問題是怎么樣排查的  

該函數(shù)直接調(diào)用libuv的uv_read_start函數(shù),三個入?yún)⒎謩e是  
1 uv_tcp_t結(jié)構(gòu)體  
2 分配內(nèi)存保存讀取的數(shù)據(jù)  
3 讀取后執(zhí)行的回調(diào)(包括讀取失敗)  
繼續(xù)往下走。  
 
nodejs問題是怎么樣排查的  

這時候nodejs就在底層注冊了一個可讀事件,等到有數(shù)據(jù)或者發(fā)送出錯的時候,會觸發(fā)上層回調(diào)(雖然只注冊了可讀事件,但是如果有錯誤發(fā)生,epoll會返回POLLIN和POLLERR事件)。這時候客戶端發(fā)送了一個rst。這時候會執(zhí)行l(wèi)ibuv的回調(diào)uv__stream_io(而不是nodejs傳進來那個,那個read_cb,read_cb是由libuv回調(diào)的)  
 
nodejs問題是怎么樣排查的  

接著我們看uv_read  
 
nodejs問題是怎么樣排查的  

重點在read函數(shù),我們不妨多看點代碼,看一下rst和read在linux下的實現(xiàn)。  
 
nodejs問題是怎么樣排查的  

上面是操作系統(tǒng)收到一個rst包時的操作。設置對應socket的錯誤信息為ECONNRESET,并設置狀態(tài)為close。如果這時候用戶執(zhí)行read會怎樣呢?  
 
nodejs問題是怎么樣排查的  

read函數(shù)會直接把錯誤信息返回給調(diào)用方。我們回到libuv中,當libuv調(diào)用read函數(shù)的時候,返回了錯誤碼ECONNRESET。然后libuv執(zhí)行nodejs的read_cb回調(diào)。如果我們還記得的話,nodejs提供的回調(diào)是OnUvRead。  
 
nodejs問題是怎么樣排查的  

nodejs套了很多層,不過我們還是找到了他,最后的MakeCallback(env->onread_string(), arraysize(argv), argv)就是執(zhí)行js層的onread函數(shù)。這個函數(shù)我們一開始的時候也提到了?;氐絥et.js。  
 
nodejs問題是怎么樣排查的  

nodejs的onread函數(shù)執(zhí)行了destroy函數(shù)。這里就不具體展開,destroy做的事情就是調(diào)用_destroy函數(shù)。然后emit一個error事件,并傳入一個Error對象(包含了錯誤碼和系統(tǒng)調(diào)用函數(shù)等信息)。觸發(fā)error事件的時候,我們就輸出了read ECONNRESET。至此,整個源碼分析過程結(jié)束。


2 抓包分析
登錄服務器,使用tcpdump工具,主要是過濾出想要的數(shù)據(jù)包。這里找出有問題的那幾個ip。過濾條件設置為

tcpdump -i any -q -A  -nn src ip1 or dst ip1 or src ip2 or dst ip2 -w tcp.cap
 

保存為cap文件,然后下載到wireshark分析(linux下分析會比較麻煩點)。最后發(fā)現(xiàn)同一個時間點,抓包和日志系統(tǒng)都輸出了相關(guān)的錯誤。

nodejs問題是怎么樣排查的  
在這里插入圖片描述
nodejs問題是怎么樣排查的  

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI