Node.js如何在没有任何信息的情况下默默崩溃?

时间:2019-09-19 17:04:40

标签: 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(`Catched!. 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
Catched!. 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

1 个答案:

答案 0 :(得分:0)

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

同时,已将解决方法添加到ssh2-sftp-client。本质上,在连接阶段添加了一个附加的“结束”侦听器,如果引发了结束事件,这将导致拒绝连接承诺。该软件包的新版本(v4.2.0)已发布,其中包含此修复程序。

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