应用程序在打开大量 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/