javascript - Node.js 如何在没有任何信息的情况下悄无声息地崩溃?

标签 javascript node.js asynchronous sftp ssh-tunnel

应用程序在打开大量 SFTP 连接时静默终止。我使用各种 process 事件处理程序,唯一触发的是 process.on('exit',...

我正在为 SFTP ssh2-sftp-client 使用 npm 包,它在下面使用 ssh2 包。

这是一个最小的可重现代码

const Client = require('ssh2-sftp-client')
const inspect = require('util').inspect

const sftpClient = new Client();

sftpClient.on('error', (err) => {
  console.log('SFTP client emitted ERROR: ' + inspect(err))
})
sftpClient.on('end', () => {
  console.log('SFTP client emitted END')
})
sftpClient.on('finish', () => {
  console.log('SFTP client emitted FINISH')
})
sftpClient.on('close', () => {
  console.log('SFTP client emitted CLOSE')
})

const options = {
  host: '',
  port: '22',
  username: '',
  password: ''
};

// below infinite loop is to simulate large number of 
// connections in my production code
(async () => {
  while (true) {
    try {
      await new Promise(resolve => setTimeout(() => resolve(sftpClient.connect(options)), 1000))
    } catch {
      console.log('boom')
    }
  }
})()

process.on('exit', code => console.log(`Caught!. Exit code: ${code}`))

process.on('uncaughtException', (err, origin) => {
  console.error('Unhandled exception. Please handle!', err.stack || err)
  console.error(`Origin: ${JSON.stringify(origin)}`)
})

process.on('unhandledRejection', (err, promise) => {
  console.error('Unhandled promise rejection. Please handle!', promise, err.stack || err)
})

process.on('warning', (warning) => {
  console.warn(warning.name)
  console.warn(warning.message)
  console.warn(warning.stack)
})

process.on('rejectionHandled', (promise) => {
  console.log('rejectionHandled event triggered')
})

如您所见,除非出现错误,否则它不应跳出无限循环。 它实际上不会进行某些迭代,但最终会逃脱 (通常在 <10 次迭代之后)。我看到的唯一日志是

SFTP client emitted END
Caught!. Exit code: 0

在 SFTP 服务器端,我在 sshd_config 文件中有以下限制

MaxSessions 1
MaxStartups 1

我正在使用:

  • Node.js 12
  • ssh2-sftp-client 4.1.0

简而言之,问题:

Node 如何在 没有任何错误事件/堆栈跟踪和退出代码 0 的情况下崩溃?

更新 #1

评论中建议对进程进行核心转储并进行分析。

如何在退出代码 0 上进行核心转储?

如果我进行核心转储,我应该在那里寻找什么?

更新#2

在存储库中创建了一个问题 https://github.com/theophilusx/ssh2-sftp-client/issues/168

最佳答案

此特定问题是由远程服务器丢弃 TCP 连接和 SSH2 库仅引发“结束”事件而没有“错误”事件的组合引起的。这已被标记为 ssh2 中的错误,并列在该模块的问题中。

与此同时,已将变通方法添加到 ssh2-sftp-client。本质上,在连接阶段添加了一个额外的“结束”监听器,如果引发结束事件,这将导致连接 promise 被拒绝。已发布包含此修复程序的新版本软件包 (v4.2.0)。

关于背景信息 - 在跟踪此问题时难以获得一致结果的部分原因部分是由于许多 SFTP 服务器(如 openSSH)的 MaxStartups 设置。此设置可以是 max:drop:full 形式的元组,其中 max 是允许的最大未验证连接(尚未完成握手和身份验证过程的连接),drop - 达到最大并满后开始丢弃的连接百分比= 开始丢弃所有连接尝试的未验证连接数。默认值通常为 10:30:60,这意味着允许 10 个未经身份验证的连接,一旦超过 10 个就开始丢弃其中的 30%,一旦出现 60 个未经身份验证的连接就丢弃所有尝试。 drop 值意味着一旦存在超过 10 个未经身份验证的连接,尝试将有 30% 的时间被丢弃,这会产生一个有点随机的结果,因为每次运行测试时,可能会丢弃不同的连接。服务器通常会在不提供任何额外信息的情况下断开连接——你可能会或可能不会通过对等错误重置,这取决于服务器如何进行断开连接(通常,你只会得到结束事件,仅此而已——不会引发错误) .

关于javascript - Node.js 如何在没有任何信息的情况下悄无声息地崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58015868/

相关文章:

javascript - 无法从 JavaScript 调用 Cloud Code

node.js - NodeJS(Express.js): How to make the Session global

javascript - 列出 OneDrive 目录内容而不递归到子目录

Node.js - EJS 示例

Android 服务器异步通信

javascript - 使用 Angularjs module.service 进行原型(prototype)继承

Javascript:如何判断 <span> 是否超过 2 行?

javascript - Angularritics2 不会触发 Google 跟踪代码管理器/分析中的路由更改

javascript - 如何在 useEffect 中管理两个函数

java - 访问用于异步 I/O 的缓冲区到底有哪些限制?