You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js应用中Tunnel-SSH无法连接MongoDB云服务器求助

解决Node.js中使用tunnel-ssh连接MongoDB云服务器的两个问题

嘿,我来帮你搞定这两个头疼的问题,咱们一步步拆解分析:


问题1:隧道建立后_connections: 0,无法确认连接状态

首先给你吃个定心丸:这个_connections: 0是正常现象!它代表的是当前通过这个SSH隧道服务建立的活跃连接数——你刚启动隧道,还没发起MongoDB请求,自然没有活跃连接,所以值为0,不代表隧道没建立成功。

验证隧道是否真的正常工作的方法:

  • 用命令行工具测试本地端口:打开终端执行telnet 127.0.0.1 27000或者nc -zv 127.0.0.1 27000,如果能收到“连接成功”的提示,说明隧道已经在本地监听端口了。
  • 查看云服务器上的MongoDB日志:登录服务器,找到MongoDB的日志文件(通常是/var/log/mongodb/mongod.log),如果隧道建立后有来自127.0.0.1的连接请求(因为你配置的dstHost是服务器本地的127.0.0.1),说明转发是正常的。
  • 加个明确的启动日志:在tunnel的回调里打印一句console.log("SSH隧道已成功启动,可以发起MongoDB请求了"),这样你就能清晰知道什么时候可以调用数据库函数了。

问题2:调用getDataFromMongoDB时返回EADDRINUSE: address already in use 127.0.0.1:27000

这个错误有两个核心原因,咱们逐个解决:

1. 最关键的错误:MongoDB连接URI写错了!

你的隧道配置是把本地27000端口转发到云服务器的27017端口,但你的代码里MongoDB连接字符串用的是localhost:27017——这相当于直接连接你本地机器的MongoDB(如果本地没装,就连不上;如果装了,也和云服务器没关系)。

修正后的URI应该指向本地的隧道端口27000:

const uri = "mongodb://USRNAME:PASSWORD_FOR_MONGDB_DATABASE@localhost:27000";

2. 本地27000端口被占用

如果修正URI后还是报这个错,那就是有其他进程在占用27000端口:

  • Windows:打开命令提示符,执行netstat -ano | findstr :27000找到占用端口的PID,然后用taskkill /PID <你的PID> /F强制杀死进程。
  • Linux/macOS:执行lsof -i :27000找到进程,再用kill -9 <你的PID>杀死。
  • 或者换个端口:把config里的localPort改成27018之类的未被占用的端口,记得同步修改MongoDB连接URI里的端口。

3. 添加隧道关闭逻辑,避免端口泄漏

之前的代码没有关闭隧道的逻辑,导致程序退出后端口可能被残留进程占用。可以在获取数据后手动关闭,或者监听程序退出信号:

// 在getDataFromMongoDB函数的finally块里关闭隧道和MongoDB连接
async function getDataFromMongoDB(tunnel) {
  // ... 原有代码 ...
  finally {
    await client2.close();
    tunnel.close();
    console.log("MongoDB连接和SSH隧道已关闭");
  }
}

// 监听程序退出信号,确保异常退出时也关闭隧道
process.on('SIGINT', () => {
  tnl.close();
  process.exit();
});

修正后的完整代码示例

const MongoClient = require("mongodb").MongoClient; // 把require移到顶部,避免重复加载
const tunnel = require("tunnel-ssh"); // 别忘了引入tunnel-ssh哦

var config = { 
  username: "root", 
  password: "password on the server", // 注意原代码里是大写的Password,tunnel-ssh要求小写password
  host: "server IP address", 
  port: 22, 
  dstHost: "127.0.0.1", 
  dstPort: 27017, 
  localHost: "127.0.0.1", 
  localPort: 27000 
};

var tnl = tunnel(config, function(error, tunnelInstance) {
  if (error) { 
    console.error("SSH隧道建立失败:", error); 
    return;
  }
  console.log("SSH隧道已成功启动!");
  getDataFromMongoDB(tunnelInstance); // 把隧道实例传入函数,方便关闭
});

async function getDataFromMongoDB(tunnel) {
  const uri = "mongodb://USRNAME:PASSWORD_FOR_MONGDB_DATABASE@localhost:27000"; // 修正端口
  const client = new MongoClient(uri, { useNewUrlParser: true });
  
  try {
    await client.connect();
    console.log("MongoDB已成功连接");
    
    const collection = client.db("my_database_name").collection("jobs");
    const jobs = await collection.find().toArray();
    console.log("获取到的jobs数据:", jobs);
  } catch (err) {
    console.error("操作出错:", err);
  } finally {
    // 确保资源被释放
    await client.close();
    tunnel.close();
    console.log("资源已释放");
  }
}

// 监听程序退出信号
process.on('SIGINT', () => {
  tnl.close();
  process.exit();
});

内容的提问来源于stack exchange,提问作者bp123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:43:57