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

432

我正在运行一个使用Socket.io的Express.js应用程序,用于聊天Web应用程序,并且在24小时内随机出现大约5次以下错误。 Node处理过程被永久包装并立即重新启动。

问题是重新启动Express会将我的用户踢出他们的聊天室,这是没有人想要的。

Web服务器由HAProxy代理。没有套接字稳定性问题,只是使用Websockets和Flashsockets传输方式。我无法故意复制此错误。

这是使用Node 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...");
    });

所以我怀疑这不是Socket.io的问题,而是我进行HTTP请求到另一个服务器或者MySQL/Redis连接时出现的问题。问题是错误堆栈并不能帮助我确定我的代码问题。这里是日志输出:

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

我该如何知道是什么原因导致这个问题?如何更好地利用这个错误?

好的,虽然不是非常详细,但这是使用 Longjohn 的堆栈跟踪:

    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)

这能是原因吗?


4
@GottZ 或许这可以帮到你(与 Node.js 相关的某个人士交流后得到的信息) https://gist.github.com/samsonradu/1b0c6feb438f5a53e30e。我今天将部署 socket.error 处理程序并告诉你。 - Samson
1
@Gottz,socket.error 处理无效,但是 process.on('uncaughtException') 可以捕获错误。这里是错误的 console.log:{ [Error: read ECONNRESET] code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read' }。 - Samson
1
ECONNRESET 可能来自网络问题。正如您所知,在测试时不可能捕获所有异常。有些异常会在生产服务器上显示出来。您需要使您的服务器更加健壮。您可以使用 Redis 作为存储来处理会话删除。这样可以使您的会话持久化,即使您的节点服务器宕机也不会丢失。 - user568109
2
为什么这与会话删除有关?它们无论如何都由Redis处理。 - Samson
3
你至少有一个TCP套接字正在侦听,但没有设置处理程序。现在是时候检查它在哪里了 :D - Moss
显示剩余9条评论
19个回答

7
我通过简单地连接到不同的网络来解决了这个问题。这是可能的问题之一。
正如上面所讨论的,ECONNRESET表示TCP会话突然关闭其连接端点。
您的互联网连接可能会阻止您连接到某些服务器。在我的情况下,我尝试连接到mLab(托管MongoDB数据库的云数据库服务)。我的ISP正在阻止它。

这个对我有用,我的代码几个小时前还能正常工作,突然间就停止了,结果发现是网络变化引起的问题。 - Aklank Jain
对我来说也是两个,谢谢 :) 我连接的是非常差的WiFi(但不知道),我换了另一个WiFi扩展器来解决它。 - Adrien V

5

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

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

之后,我尝试了相同的npm命令,好消息是它成功了。我不确定解决问题是否如此简单。

我正在使用CENTOS 7。


5
我刚刚在我的使用情况下找到了解决方法。 我一直收到"ECONNRESET"错误。 原来,我的客户端设置方式是以非常快的速度多次向服务器发送API调用 - 它只需要一次命中端点。 当我修复了这个问题时,错误就消失了。

4
我遇到了同样的问题,看起来是Node.js版本的问题。
我安装了先前的Node.js版本(10.14.2),使用nvm(允许您安装多个Node.js版本并快速切换版本)后一切正常。
这不是一个“干净”的解决方案,但它可以暂时为您服务。

0
尝试将这些选项添加到socket.io中:
const options = { transports: ['websocket'], pingTimeout: 3000, pingInterval: 5000 };

我希望这可以帮助你!


0

我尝试了几个选项,作为临时解决方案:

  1. 如果使用node,请尝试使用node use #version#在不同的node版本之间切换。对我有用。
  2. 尝试切换互联网连接。

0
当我运行我的应用程序时,首先出现了ECONNRESET错误,之后出现了ECONNREFUSED错误。在运行我的nodeapp时,我遇到了这两个问题。对于这两个问题,我发现这是因为没有启动wampserver而导致的。我在我的应用程序中使用mysql数据库来获取数据,并借助wampserver的帮助。我通过启动wampserver,然后再运行我的node app来解决这个问题。它可以正常工作。您可以使用node或nodemon来运行node应用程序,在我的情况下并不是问题。

0

Node JS的套接字是非阻塞IO。考虑使用其他来源的非阻塞IO连接。例如,如果您在Node中使用阻塞Java套接字,则仅能工作几秒钟,之后将返回错误。通过实现非阻塞连接(即使用选择器的socketchannel),可以缓解此问题。


0
在我的情况下,node 版本是问题所在。应用程序在 v16.14.2 下报错 ECONNRESET,但在 v18.16.0 下正常运行。我使用 n 来管理 node 版本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接