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

179 浏览
0 Comments

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

我正在运行一个使用Socket.io的Express.js应用程序,用于聊天网页应用。在24小时内,我随机遇到以下错误大约5次。Node进程被永久包装起来,它会立即重新启动。问题在于重新启动Express会让我的用户退出他们的聊天室,而没有人想要这样。Web服务器由HAProxy代理。没有任何socket稳定性问题,只是使用了websocket和flashsocket传输。我无法有意地再现这个错误。这是使用Node v0.10.11的错误:\n

    events.js:72
            throw er; // Unhandled 'error' event
                  ^
    Error: read ECONNRESET     // 或者是'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

\n编辑(2013-07-22)\n添加了socket.io客户端错误处理程序和未捕获的异常处理程序。\n似乎这个可以捕获错误:\n

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

\n所以我怀疑这不是Socket.io的问题,而是我对另一个服务器的HTTP请求或MySQL/Redis连接。问题在于错误堆栈并没有帮助我确定我的代码问题。这是日志输出:\n

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

\n我如何知道是什么原因导致这个错误?我如何从错误中获得更多信息?\n好的,不是很详细,但是这是使用Longjohn的堆栈跟踪:\n

    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] ] } }

\n在这里我提供flash socket策略文件:\n

    net = require("net")
    net.createServer( (socket) =>
      socket.write("\n")
      socket.write("\n")
      socket.write("\n")
      socket.write("\n")
      socket.write("\n")
      socket.end()
    ).listen(843)

\n这可能是原因吗?

0
0 Comments

问题的出现原因是因为在Node版本v0.9.10中,当客户端断开连接时,会抛出错误ECONNRESET。之前的版本不会因为客户端的中断而报错。我认为这是Node的预期功能,所以解决方法是处理这个错误,我在net.socket处理程序中进行了处理。

解决方法是在代码中处理错误,比如在未捕获的异常处理程序中。您可以通过以下步骤来演示:

1. 创建一个简单的socket服务器,并使用Node v0.9.9和v0.9.10来启动它:

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

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

3. 然后从客户端断开连接(我只是按Ctrl-C)。

4. 当使用Node v0.9.9时,您不应该看到任何错误,当使用Node v.0.9.10及更高版本时,您将看到错误。

在生产环境中,我使用的是v0.10.x版本,仍然会出现这个错误。所以解决办法是在代码中处理这个错误。

感谢您的阅读,我自己解决了这个问题!重要的是不要让错误传播到未捕获的异常,因为这会使整个应用程序不稳定。例如,在捕获了大约10个ECONNRESET错误之后,服务器有时会变得无响应(冻结并且不处理任何连接)。

我也了解到了Node版本更改,不再抑制这个错误,但是考虑到每个版本都会出现很多问题并且得到解决,我更倾向于使用最新的版本。我现在正在使用V0.10.13版本。

0
0 Comments

问题:如何调试Node.js中的ECONNRESET错误?

原因:这个问题是由于我为提供Flash策略文件而创建的简单TCP服务器引起的。现在我可以使用处理程序来捕获错误。

解决方法:在错误处理程序中调用socket.destroy()来确保关闭socket。

以下是示例代码:

// serving the flash policy file
const 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.destroy();
  });
  socket.write("\n");
  socket.write("\n");
  socket.write("\n");
  socket.write("\n");
  socket.write("\n");
  socket.end();
}).listen(843);

以上代码可以解决ECONNRESET错误,并确保安全关闭socket。

希望对你有所帮助!

0
0 Comments

"ECONNRESET"错误是由于TCP连接的另一端突然关闭连接引起的。这很可能是由于一个或多个应用程序协议错误。可以查看API服务器日志以查看是否有错误信息。为了检查错误并潜在地调试问题,可以参考在stackoverflow上发布的与类似问题相关的"如何调试NodeJS中的套接字挂起错误?"。

快速而不完整的开发解决方案:使用longjohn,它可以提供包含异步操作的长堆栈跟踪。

干净而正确的解决方案是,在Node中,每当发出一个"error"事件而没有任何监听器时,它将抛出错误。为了防止抛出错误,需要在其上添加一个监听器并自行处理。这样,可以记录包含更多信息的错误。

要为一组调用添加一个监听器,可以使用domain,并在运行时捕获其他错误。确保与代码的其他部分相比,每个与http(Server/Client)相关的异步操作都位于不同的domain上下文中,域将自动监听"error"事件并将其传播到自己的处理程序。因此,只需要监听该处理程序并获取错误数据。此外,还可以免费获得更多信息。

另外,"ECONNRESET"错误意味着TCP会话的另一端突然关闭了连接。这很可能是由于一个或多个应用程序协议错误。可以查看API服务器日志以查看是否有错误信息。

可能还有一种情况:在随机的时间,另一端过载并且简单地关闭连接。这取决于您连接到的确切内容...

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

它不一定意味着"突然关闭"。通常是由于向已经正常关闭的连接写入导致的。这将导致发出RST。

当我从浏览器(Chrome)批量发送大约100个API调用进行测试时,我会抛出此错误。我想象Chrome必须变得过载并终止一些连接... 在不重新启动服务器的情况下,为什么不能在自己的域中处理每个请求并捕获域错误?

几乎总是应该在未捕获的异常后重新启动服务器,因为您的数据、应用程序和Node.js本身处于未知状态。在异常后继续运行会将您的数据置于风险之中。如果想要了解更多信息,请查看Node关于进程的文档Node关于域的文档

这个错误在生产中出现吗?

0