我如何调试错误ECONNRESET在Node.js?

我正在运行一个Express.js应用程序使用Socket。IO的聊天网络应用程序 我在24小时内随机得到了5次以下错误。

问题是重新启动Express会把我的用户踢出他们的房间

web服务器使用HAProxy代理。插座不存在稳定性问题, 只是使用websockets和flashsockets传输。

这是节点v0.10.11的错误:

    events.js:72
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET     //alternatively it s a 'write'
at errnoException (net.js:900:11)
at TCP.onread (net.js:555:19)
error: Forever detected script exited with code: 8
error: Forever restarting script for 2 time

编辑(2013-07-22)

增加both socket。IO客户端错误处理程序和未捕获的异常处理程序。

似乎捕获了错误
    process.on('uncaughtException', function (err) {
console.error(err.stack);
console.log("Node NOT Exiting...");
});
所以我怀疑它不是一个Socket。发送HTTP请求到另一个服务器 或者MySQL/Redis连接。问题在于错误堆栈 不能帮我找出我的代码问题。日志输出如下:

    Error: read ECONNRESET
at errnoException (net.js:900:11)
at TCP.onread (net.js:555:19)

我怎么知道是什么引起的呢?我如何从错误中得到更多?

好吧,不是很啰嗦,但这里是与朗约翰的堆栈跟踪:

    Exception caught: Error ECONNRESET
{ [Error: read ECONNRESET]
code: 'ECONNRESET',
errno: 'ECONNRESET',
syscall: 'read',
__cached_trace__:
[ { receiver: [Object],
fun: [Function: errnoException],
pos: 22930 },
{ receiver: [Object], fun: [Function: onread], pos: 14545 },
{},
{ receiver: [Object],
fun: [Function: fireErrorCallbacks],
pos: 11672 },
{ receiver: [Object], fun: [Function], pos: 12329 },
{ receiver: [Object], fun: [Function: onread], pos: 14536 } ],
__previous__:
{ [Error]
id: 1061835,
location: 'fireErrorCallbacks (net.js:439)',
__location__: 'process.nextTick',
__previous__: null,
__trace_count__: 1,
__cached_trace__: [ [Object], [Object], [Object] ] } }

这里我提供了flash套接字策略文件:

    net = require("net")
net.createServer( (socket) =>
socket.write("<?xml version=\"1.0\"?>\n")
socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n")
socket.write("<cross-domain-policy>\n")
socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n")
socket.write("</cross-domain-policy>\n")
socket.end()
).listen(843)

这是原因吗?

926834 次浏览

您可能已经猜到了:这是一个连接错误。

“ECONNRESET”表示TCP会话的另一端突然关闭了连接的一端。这很可能是由于一个或多个应用程序协议错误。您可以查看API服务器日志,看看它是否抱怨了什么。

但是因为你也在寻找一种方法来检查错误和调试问题,你应该看看如何在NodeJS中调试套接字挂起错误?< / >”,它张贴在stackoverflow上,与一个类似的问题有关。

快速和肮脏的开发解决方案:

使用longjohn,您将获得包含异步操作的长堆栈跟踪。

< p > 清洁正确的溶液: 技术上,在节点中,只要如果你触发一个'error'事件,但没有人监听它,它就会抛出.;为了使它不抛出,在它上面放置一个侦听器并自己处理它。

要为一组调用设置一个监听器,可以使用并在运行时捕获其他错误。确保与http(服务器/客户端)相关的每个异步操作与代码的其他部分相比处于不同的上下文中,域将自动侦听error事件并将其传播到它自己的处理程序。因此,您只侦听该处理程序并获得错误数据。你还可以免费获得更多信息。

编辑(2013-07-22)

正如我上面所写的:

“ECONNRESET”表示TCP会话的另一端突然关闭了连接的一端。这很可能是由于一个或多个应用程序协议错误。您可以查看API服务器日志,看看它是否抱怨了什么。

也有可能是这样的情况:在任意时间,另一端过载,结果只是终止连接。如果是这样的话,这取决于你连接的到底是什么……

但有一件事是肯定的:你的TCP连接上确实有一个读取错误,导致异常。您可以通过查看您在编辑中发布的错误代码来确认这一点。

我遇到过类似的问题,在升级Node后,应用程序开始出错。我相信这可以追溯到Node v0.9.10版本的这一项:

  • net:不压制ECONNRESET (Ben Noordhuis)

以前的版本不会在客户端中断时出错。来自客户端的连接中断会在Node中抛出错误ECONNRESET。我相信这是Node的预期功能,因此修复(至少对我来说)是处理错误,我相信您在unCaught异常中做到了这一点。虽然我在网上处理。套接字处理程序。

你可以这样演示:

创建一个简单的套接字服务器,并获得Node v0.9.9和v0.9.10。

require('net')
.createServer( function(socket)
{
// no nothing
})
.listen(21, function()
{
console.log('Socket ON')
})

使用v0.9.9启动它,然后尝试通过FTP传输到此服务器。我使用FTP和端口21只是因为我在Windows上,有一个FTP客户端,但没有telnet客户端方便。

然后从客户端断开连接。(我正在按Ctrl-C)

在使用Node v0.9.9时应该看到NO ERROR,在使用Node v.0.9.10及更高版本时应该看到ERROR。

在生产环境中,我使用v.0.10。它仍然会给出错误。同样,我认为这是有意的,解决方案是处理代码中的错误。

一个简单的tcp服务器,我提供的flash策略文件导致了这个问题。我现在可以使用处理程序捕获错误:

# serving the flash policy file
net = require("net")


net.createServer((socket) =>
//just added
socket.on("error", (err) =>
console.log("Caught flash policy server socket error: ")
console.log(err.stack)
)


socket.write("<?xml version=\"1.0\"?>\n")
socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n")
socket.write("<cross-domain-policy>\n")
socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n")
socket.write("</cross-domain-policy>\n")
socket.end()
).listen(843)

是的,您提供的策略文件肯定会导致崩溃。

重复一下,只需在代码中添加一个延迟:

net.createServer( function(socket)
{
for (i=0; i<1000000000; i++) ;
socket.write("<?xml version=\"1.0\"?>\n");
…

并使用telnet连接到端口。如果在延迟过期之前断开telnet连接,当socket时将会出现崩溃(未捕获异常)。Write抛出错误。

为了避免这里的崩溃,只需在读写套接字之前添加一个错误处理程序:

net.createServer(function(socket)
{
for(i=0; i<1000000000; i++);
socket.on('error', function(error) { console.error("error", error); });
socket.write("<?xml version=\"1.0\"?>\n");
}

当您尝试上面的断开连接时,您只会得到一条日志消息,而不是崩溃。

当你完成时,记得删除延迟。

我也面临着同样的问题,但我通过以下方式缓解了它:

server.timeout = 0;

server.listen之前。server在这里是一个HTTP服务器。默认超时时间是2分钟,根据API文档

今天遇到了同样的问题。 经过一些研究,我发现一个非常有用的--abort-on-uncaught-exception node.js选项。它不仅提供了更详细和有用的错误堆栈跟踪,而且还保存了应用程序崩溃时的核心文件,允许进一步调试

另一种可能的情况(但很罕见)是,如果你有服务器到服务器的通信,并将server.maxConnections设置为一个非常低的值。

在节点的核心库net.js中,它将调用clientHandle.close(),这也将导致错误ECONNRESET:

if (self.maxConnections && self._connections >= self.maxConnections) {
clientHandle.close(); // causes ECONNRESET on the other end
return;
}

我通过正在连接到不同的网络简单地解决了这个问题。这是可能出现的问题之一。

如上所述,ECONNRESET意味着TCP会话突然关闭连接的末端。

您的互联网连接可能阻止您连接到某些服务器。在我的例子中,我试图连接到mLab(托管MongoDB数据库的云数据库服务)。我的网络服务提供商屏蔽了它。

尝试将这些选项添加到socket.io:

const options = { transports: ['websocket'], pingTimeout: 3000, pingInterval: 5000 };

我希望这对你有帮助!

我也得到ECONNRESET错误在我的开发过程中,我解决它的方式是通过使用nodemon启动我的服务器,只是使用"node server.js"启动我的服务器修复了我的问题。

这很奇怪,但它为我工作,现在我再也没有看到ECONNRESET错误了。

我也有这个错误,经过几天的调试和分析后,我能够解决它:

我的解决方案

对我来说,VirtualBox(用于Docker)是一个问题。我在我的虚拟机上配置了端口转发,错误只发生在转发的端口上。

一般的结论

以下观察可以帮你节省我不得不投入的工作时间:

  • 对我来说,这个问题只发生在一个端口上从本地主机到本地主机的连接上。->检查改变任何这些常数解决问题。
  • 对我来说,问题只发生在我的机器->让别人试试。
  • 对我来说,这个问题只发生在一段时间后,无法可靠地再现
  • 无法使用任何节点或表达式(调试)工具检查“我的问题”。-别在这上面浪费时间了

找出是否有什么东西在你的网络(-settings),如虚拟机,防火墙等,这可能是问题的原因。

我通过以下方法解决了这个问题:

  • 关闭我的wifi/以太网连接并打开。
  • 我在终端中输入:npm update来更新npm。
  • 我试图退出会话并重新登录

之后,我尝试了相同的npm命令,好的事情是它成功了。我不确定是不是那么简单。

我用的是CENTOS 7

我也有同样的问题,似乎是Node.js版本的问题。

我安装了以前版本的Node.js(10.14.2),使用nvm一切正常(允许你安装几个版本的Node.js,并快速从一个版本切换到另一个版本)。

这不是一个“干净”的解决方案,但它可以暂时为你服务。

我刚刚算出来了,至少在我的用例中。

我得到ECONNRESET。事实证明,我的客户端设置的方式是,它用API调用大量地快速地访问服务器,而它只需要访问端点一次。

当我修复它时,错误就消失了。

Node JS套接字不阻塞io。考虑使用来自其他源的非阻塞io连接。例如,如果使用带有node的阻塞Java套接字,它只会工作几秒钟,之后就会出现错误。通过实现一个非阻塞的连接来缓解这个问题,例如带有选择器的socketchannel。

ECONNRESET发生在服务器端关闭TCP连接并且您对服务器的请求没有完成时。服务器响应消息,表明您引用的连接无效。

为什么服务器发送无效连接的请求?

假设您在客户机和服务器之间启用了保持连接。配置保持连接超时时间为15秒。这意味着如果keep-alive空闲15秒,它将发送连接关闭请求。所以15秒后,服务器告诉客户端关闭连接。,当服务器端发送这个请求时,客户端发送一个新的请求,这个请求已经在发送到服务器端。由于此连接现在无效,服务器将拒绝ECONNRESET错误。因此,由于发送到服务器端的请求较少,所以出现了问题。所以请禁用keep-alive,它将工作正常。

首先我运行我的应用程序,我得到了ECONNRESET,之后我得到了类似ECONNREFUSED的错误。我在运行我的节点 应用程序时遇到了这两个问题。对于这两个问题,我发现这是因为 启动wampserver。我在我的应用程序中使用mysql数据库在wampserver的帮助下获取数据。我通过启动wampserver,然后运行我的节点应用程序来解决这个问题。它工作得很好。您可以使用node或nodemon来运行节点应用程序。在我的情况下,这不是问题。

我尝试了一些选择,并将其作为临时解决方案

  1. 如果使用node,尝试使用node use #version#在不同的节点版本之间切换。为我工作
  2. 尝试切换网络连接