我正在使用Socket运行一个Express.js应用程序。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)

增加了两个socket。IO客户端错误处理程序和未捕获的异常处理程序。 这个似乎捕获了错误:

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

所以我怀疑这不是插座。发送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)

这是原因吗?


当前回答

另一种可能的情况(但很少见)是,如果您有服务器到服务器的通信,并且设置了服务器。maxConnections的值非常低。

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

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

其他回答

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

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

但是因为你也在寻找一种方法来检查错误并调试这个问题,你应该看看“如何调试NodeJS中的套接字挂起错误?”这篇文章是在stackoverflow上发布的,与一个类似的问题有关。

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

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

干净正确的解决方案: 从技术上讲,在node中,每当你发出'error'事件而没有人侦听它时,它就会抛出。为了使它不抛出,在它上面放置一个侦听器并自己处理它。这样,您就可以用更多的信息记录错误。

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

编辑(2013-07-22)

正如我上面所写的:

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

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

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

当服务器端关闭TCP连接并且您对服务器的请求没有得到满足时,将发生ECONNRESET。服务器响应消息,表明您引用的连接无效。

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

Suppose you have enabled a keep-alive connection between client and server. The keep-alive timeout is configured to 15 seconds. This means that if keep-alive is idle for 15 seconds, it will send connection close request. So after 15 seconds, server tells the client to close the connection. BUT, when server is sending this request, client is sending a new request which is already on flight to the server end. Since this connection is invalid now, server will reject with ECONNRESET error. So the problem occurs due to fewer requests to the server end. So please disable keep-alive and it will work fine.

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

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

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

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

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

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

我用的是CENTOS 7

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

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

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