我正在使用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)

这是原因吗?


当前回答

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

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

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

我用的是CENTOS 7

其他回答

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

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

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");
}

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

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

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

我的解决方案

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

一般的结论

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

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

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

当服务器端关闭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会话的另一端突然关闭了它的连接端。这很可能是由于一个或多个应用程序协议错误。您可以查看API服务器日志,看看它是否抱怨了什么。

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

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

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

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

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

编辑(2013-07-22)

正如我上面所写的:

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

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

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

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

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