【问题标题】:How to find the source of a connect ECONNREFUSED error in node.js?如何在 node.js 中找到连接 ECONNREFUSED 错误的来源?
【发布时间】:2015-07-07 17:47:14
【问题描述】:

我继承了一个具有合理复杂性的 nodejs 应用程序。它通过各种网络接口与其他 5 个应用程序交互,主要是 HTTP REST API。时不时地我遇到一个抛出错误的问题,虽然它被处理以防止应用程序崩溃,但我不知道错误来自哪里。以下是我从该错误中获得的典型信息量:

就是这样。这就是整个消息和堆栈跟踪(消息实际上在errno=ECONNREFUSEDsyscall=connect 中重复,没有帮助)。我正在使用 nodejs 0.12.2 并将堆栈跟踪行相应地链接到源。我已经阅读了源代码,但没有得到任何地方。

我还查看了关于 SO 与 ECONNREFUSED 相关的许多问题,但这些问题总是带有代码示例。如果我知道我的应用程序的哪一部分是对网络请求的响应,我可以修复它。

所以我的问题是,我如何检测节点应用程序以找出像这样的失败请求来自哪里?

PS:我也看过the recommendations for debugging nodejs applications,但没有找到任何答案。

【问题讨论】:

  • 来自POSIX connect system call reference for ECONNREFUSED:“目标地址没有监听连接或拒绝连接请求。”最可能的原因?没有人在您尝试连接的地址/端口上监听连接。如果有有人在听,那么你检查过你的防火墙了吗?
  • 在查看代码之前,为什么不从 tcpdump(或 Wireshark)和 Fiddler 开始,以确定哪个服务器和服务拒绝连接?使用 tcpdump(或 Wireshark),您可以找出拒绝它的 IP 和端口。使用 Fiddler,如果它是一个偶尔归档的请求,您可以了解哪个失败(通过查看以前的请求)并且您可以通过 SSL 查看请求。这会给你一个初步的想法。
  • @rodolk 谢谢,这是个好主意,但如果问题只发生在我无法运行这些工具的系统上,也可能不切实际。

标签: javascript node.js network-programming


【解决方案1】:

以下 sn-p 记录所有 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
}

我已经在生产环境中运行了一周,它帮助识别了原本无法确定的连接问题。

options 对象的属性不仅仅是href,尽管那是对我最有用的一个。这是我做的测试的完整列表: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

上面的sn-p是基于a gist someone wrote for me在看到我在推特上的感叹之后。

【讨论】:

    【解决方案2】:

    该错误是由于主机拒绝从内核返回的 TCP 连接引起的 - 您需要进行一些错误处理并重试尝试以避免这些问题。尝试cUrling URL 以确保它不是您的机器的问题。

    您可以使用domain 模块来封装代码并确保保留发生错误的上下文。此外,您应该始终为回调等创建命名函数,因为这至少会为您指明正确的方向。

    如果您需要的话,还有一些库可以尝试重试 HTTP 请求等。

    【讨论】:

    • 如果我知道要查看应用程序中的哪些代码,我可以做所有这些事情。但我的问题是关于找到该代码。命名回调将无济于事,因为我的回调从未被调用,正如您在我放入问题的堆栈跟踪中看到的那样。
    • 添加 longjohn 模块只会导致我的应用程序立即崩溃,看起来它会将已处理的异常变成未处理的异常。
    • 如果你使用 node-inspector,你可以在调用外部资源的位置放置断点(这就是它的样子),看看哪个给你带来了麻烦。您也可以将console.logs 放在拨打这些电话的区域周围。在这种情况下,除了运行单元测试来寻找覆盖范围内的故障点(使用类似 istanbul 之类的覆盖范围)之外,这些确实是我唯一知道要做的事情。
    猜你喜欢
    • 1970-01-01
    • 2015-07-27
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    相关资源
    最近更新 更多