Node.js中通过SSH隧道执行mongodump报ECONNRESET错误问题
问题根因
这个报错是SSH隧道关闭时机不合理导致的:mongodump 执行完成触发回调时,其和隧道之间的TCP连接还有未处理的残留网络数据,此时直接调用server.close() 会强制切断连接,触发ECONNRESET 报错,该报错不影响备份文件的完整性,属于关闭阶段的无害提示。
修复方案
- 方案1:监听隧道服务的错误事件,忽略合法的重置报错
因为备份文件已经正常生成,你可以主动捕获隧道关闭时的这类错误,避免抛出到全局 - 方案2:延迟关闭隧道,等待TCP连接数据处理完成
不要在exec回调触发后立刻关闭隧道,增加短时间延迟后再执行关闭操作 - 优化项:补充隧道创建错误的处理逻辑,原有代码忽略了
tunnel回调的错误参数,异常场景下会出现无响应的问题
修复后代码示例
const sshConfig = { username: process.env.BACKUP_MONGO_USER, port: 22, dstPort: 27017, localPort: 27018, host: process.env.BACKUP_MONGO_HOST, dstHost: '127.0.0.1', localHost: '127.0.0.1', privateKey: fs.readFileSync(process.env.BACKUP_MONGO_FILE), keepAlive: true, }; const connection = new Promise((resolve, reject) => { tunnel(sshConfig, (err, server) => { if (err) return reject(err) // 监听错误,过滤ECONNRESET server.on('error', (e) => { if (e.code !== 'ECONNRESET') { console.error('隧道异常', e) } }) resolve({ server }); }, ); }); async function dbDump() { try { const { server } = await connection; console.log('Connection Successful'); const command = `mongodump --db <dbName> --collection <collectionName> --host localhost --port 27018`; exec(command, (err, stdout, stderr) => { if(err) { console.log('执行mongodump错误', err); } if(stderr) { console.log('mongodump标准错误输出', stderr); } if(stdout) { console.log('mongodump标准输出', stdout); } // 延迟500ms关闭隧道,等待底层连接清空 setTimeout(() => { server.close(() => { console.log('隧道已关闭') process.exit(0) }); }, 500) }); } catch (e) { console.error('隧道创建失败', e) process.exit(1) } } dbDump();
内容的提问来源于stack exchange,提问作者b3a
相关产品推荐
相关产品推荐

