2015-06-29 87 views
1

我已經繼承了具有合理複雜性的nodejs應用程序。它通過各種網絡接口與其他5個應用程序進行交互,主要是HTTP REST API。我偶爾會遇到一個拋出錯誤的問題,並且在處理它來防止應用程序崩潰時,我無法確定錯誤來自哪裏。下面是我從這個錯誤中獲得的信息的典型量:如何在node.js中找到連接ECONNREFUSED錯誤的來源?

就是這樣。這是整個消息和堆棧跟蹤(消息實際上在errno=ECONNREFUSEDsyscall=connect中重複,沒有幫助)。我使用nodejs 0.12.2並相應地將棧跟蹤鏈接到源。我已經閱讀了源代碼,但沒有得到任何答案。

我也瀏覽了許多與SO有關的問題,這些問題與ECONNREFUSED有關,但這些問題總是帶有代碼示例。如果我知道我的應用程序的哪一部分是網絡請求的響應,我可以修復它。

所以我的問題是,我如何測試一個節點應用程序來找出這樣的失敗請求來自哪裏? PS:我也看過the recommendations for debugging nodejs applications,但沒有找到任何答案,我的問題。

+0

從'ECONNREFUSED'的[POSIX'connect'系統調用參考](http://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html):「目標地址沒有監聽連接或拒絕了連接請求。「最有可能的原因?沒有人在您試圖連接的地址/端口上監聽連接。如果有*有人在傾聽,那麼你有沒有檢查你的防火牆? –

+1

在查看代碼之前,爲什麼不從tcpdump(或Wireshark)和Fiddler開始,以確定哪個服務器和服務拒絕連接?使用tcpdump(或Wireshark),你可以找到拒絕它的IP和端口。使用Fiddler,如果它是一段時間的文件請求,您可以瞭解哪個請求失敗(通過查看以前的請求),並且您可以通過SSL查看請求。這會給你一個第一個想法。 – rodolk

+0

@rodolk謝謝,這是一個好主意,但如果問題只發生在我無法運行這些工具的系統上,也可能不切實際。 –

回答

0

以下片段記錄了所有的HTTP連接錯誤,獨立的他們的呼叫網站:

// install error handler on all sockets to provide context for ECONNREFUSED and smilar errors 
// this is not an official API and may break at some point 
// it will also likely log this error multiple times, which the socketErrorId helps identify 
var http = require('http'); 
var net = require('net'); 
var errorCounter = 0; 
http.globalAgent.createConnection = function (options) { 
    var socket = net.createConnection(options) 
    socket.on('error', function (error) { 
    errorCounter += 1; 
    error.socketErrorId = errorCounter; 
    console.log('socket error, while connecting to ', options.href, error); 
    }) 
    return socket 
} 

我現在已經在生產了一個星期這個運行,它幫助確定了,否則無法連接問題放下。

選項對象的屬性不僅僅是href,儘管這對我來說是最有用的。下面是一個測試,我做了一個完整的列表:看到在Twitter上我lamentions後domain, _events, _maxListeners, callback, uri, headers, method, readable, writable, explicitMethod, _qs, _auth, _oauth, _multipart, _redirect, _tunnel, setHeader, hasHeader, getHeader, removeHeader, localAddress, pool, dests, __isRequestRequest, _callback, proxy, tunnel, setHost, originalCookieHeader, _disableCookies, _jar, port, host, path, httpModule, agentClass, agent, _started, href, servername, encoding

的片段上方是基於a gist someone wrote for me

0

錯誤是由主機拒絕從內核返回的TCP連接引起的 - 您需要執行一些錯誤處理並重試嘗試以避免這些問題。嘗試cUrl URL以確保它不是您的機器有問題。

您可以使用domain模塊來封裝代碼並確保保留髮生錯誤的上下文。另外,你應該總是爲回調等命名函數,因爲這至少會指向正確的方向。

還有一些庫可以嘗試重試HTTP請求等,如果這是你所需要的。

+0

如果我知道應用程序中需要查看哪些代碼,我可以做所有這些事情。但我的問題是關於尋找代碼。 命名回調沒有幫助,因爲我從未調用回調函數,正如您在問題中提到的堆棧跟蹤中所看到的那樣。 –

+0

添加longjohn模塊只會導致我的應用程序立即崩潰,看起來它會將處理的異常轉換爲未處理的異常。 –

+0

如果您使用節點檢查器,您可以在調用外部資源的位置放置斷點(這看起來像這樣),並查看哪個節點會給您帶來麻煩。你也可以把'console.log'放在那些調用的地方。在這種情況下,除了運行單元測試來尋找覆蓋失敗點(使用諸如istanbul進行覆蓋)之外,這些確實是唯一可以做的事情。 – theWanderer4865

相關問題