Node js ECONNRESET

问题描述 投票:269回答:13

我正在通过socket.io运行Express js应用程序进行聊天webapp,我在以下期间大约5次随机收到以下错误24小时节点进程被永久封装,并重新启动本身。

问题是重新启动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

EDIT(2013-07-22)

同时添加了socket.io客户端错误处理程序和未捕获的异常处理程序。似乎这是抓到错误了:

process.on('uncaughtException', function (err) {
  console.error(err.stack);
  console.log("Node NOT Exiting...");
});

因此,我怀疑这不是socket.io问题,而是对我执行的另一台服务器或mysql / redis连接的http请求。问题是错误堆栈无法帮助我识别代码问题。这是日志输出:

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

我怎么知道是什么原因造成的?我如何从错误中得到更多?

好吧,不是很冗长,但是这里是带有“ longjohn”的stacktrace:

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)

这可能是原因吗?

node.js sockets tcp express
13个回答
239
投票

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

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

但是由于您还正在寻找一种检查错误并可能调试问题的方法,因此您应该查看一下关于同一个问题的stackoverflow上发布的How to debug a socket hang up error in NodeJS?

快速而肮脏的开发解决方案

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

干净且正确的解决方案:从技术上讲,在节点中,每当you emit an 'error' event and no one listens to it, it will throw。要使其不被抛出,请在其上放置一个侦听器并自己处理。这样,您可以记录错误的更多信息。

要在一组呼叫中使用一个侦听器,您可以使用'error',也可以在运行时捕获其他错误。与代码的其他部分相比,确保与http(Server / Client)相关的每个异步操作都在不同的domains上下文中,该域将自动侦听domain事件,并将其传播到它自己的处理程序中。因此,您只听该处理程序并获取错误数据。 error

EDIT(2013-07-22)

正如我在上面写的:

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

也可能是这种情况:在随机时间,另一侧过载,结果只是终止了连接。如果是这种情况,请完全取决于您要连接的内容...

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


2
投票

我仅通过连接到其他网络就解决了这个问题。这是可能的问题之一。

如上所述,ECONNRESET表示TCP会话突然关闭了其连接的末端。

您的互联网连接可能会阻止您连接到某些服务器。就我而言,我试图连接到mLab(托管MongoDB数据库的云数据库服务)。而且我的ISP阻止了它。


2
投票

我通过以下方式解决了此问题:

  • 关闭我的wifi /以太网连接,然后再打开。
  • 我在终端输入:net.createServer( function(socket) { for(i=0; i<1000000000; i++); socket.on('error', function() { console.log("error"); }); socket.write("<?xml version=\"1.0\"?>\n") 更新npm。
  • 我尝试从会话中注销并再次登录

之后,我尝试了相同的npm命令,但是好了,它解决了。我不确定是否那么简单。

我正在使用CENTOS 7


0
投票

我有同样的问题,看来是Node.js版本是问题。

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

这不是一个“干净”的解决方案,但可以为您提供临时服务。


-1
投票

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

"node server.js"

希望这对您有帮助!


36
投票

我用于提供Flash策略文件的一个简单的tcp服务器导致了此情况。我现在可以使用处理程序来捕获错误:

You also get more information for free.

26
投票

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

  • 净额:不要压制ECONNRESET(Ben Noordhuis)

以前的版本不会因客户端中断而出错。来自客户端的连接中断将在节点中引发错误ECONNRESET。我相信这是Node的预期功能,因此(至少对我来说)修复是为了处理错误,我相信您是在未捕获的异常中完成的。尽管我在net.socket处理程序中处理它。

您可以证明这一点:

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

# 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)

使用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。东西,它仍然会给出错误。同样,我认为这是有意的,解决方案是处理代码中的错误。


15
投票

今天遇到了同样的问题。经过一番研究,我发现了一个非常有用的require('net') .createServer( function(socket) { // no nothing }) .listen(21, function() { console.log('Socket ON') }) 。它不仅提供了更多详细和有用的错误堆栈跟踪,而且还保存了应用程序崩溃时的核心文件,允许进一步调试。


13
投票

我也遇到过同样的问题,但我通过放置以下内容缓解了它:

--abort-on-uncaught-exception node.js option

--abort-on-uncaught-exception之前。 server.timeout = 0; 是这里的HTTP服务器。根据server.listen,默认超时为2分钟。


9
投票

[另一种可能的情况(但罕见)是,如果您具有服务器之间的通信,并且将server设置为非常低的值。

在节点的核心库API documentation中,它将调用server.maxConnections,这也会导致错误ECONNRESET:

net.js

7
投票

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

要重复,只需在您的代码中添加延迟:

clientHandle.close()

…并使用if (self.maxConnections && self._connections >= self.maxConnections) { clientHandle.close(); // causes ECONNRESET on the other end return; } 连接到端口。如果在延迟到期之前断开telnet的连接,则在socket.write引发错误时会崩溃(未捕获的异常)。

为了避免此处崩溃,只需在读取/写入套接字之前添加错误处理程序:

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

[尝试上述断开连接时,您只会收到一条日志消息,而不是崩溃。

完成后,请记住要消除延迟。


5
投票

我在开发过程中也收到ECONNRESET错误,解决方法是通过not使用nodemon启动服务器,只需使用telnet启动服务器即可解决我的问题。

这很奇怪,但是对我有用,现在我再也看不到ECONNRESET错误。


3
投票

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

我的解决方案

对我来说,VirtualBox(对于Docker)是个问题。我在VM上配置了端口转发,并且错误仅在转发的端口上发生。

一般结论

以下观察结果可能为您节省我不得不投资的工作时间:

  • 对我来说,问题仅发生在一个端口上从本地主机到本地主机的连接上。 ->检查更改任何这些常数即可解决问题。
  • 对我来说,问题仅发生在我的机器上->让其他人尝试。
  • 对我来说,问题仅在一段时间后发生,无法可靠地再现
  • 无法用任何节点或表达(调试)工具检查我的问题。 ->不要在此浪费时间

->弄清您的网络(设置)是否有混乱,例如VM,防火墙等,这可能是问题的原因。

© www.soinside.com 2019 - 2024. All rights reserved.