通过SSH隧道在Java中连接Mongo数据库

36

已修复 (编辑代码以反映我所做的更改)

我正在尝试使用Java通过SSH隧道连接到Mongo数据库。

我正在使用Mongo驱动程序3.0.2和jcraft(JSch)创建SSH隧道。 我的想法是:

  • 通过SSH连接到托管MongoDB安装的机器
  • 设置端口转发,将本地端口转发到远程MongoDB端口
  • 远程连接到MongoDB

我的代码如下:

// forwarding ports
private static final String LOCAL_HOST = "localhost";
private static final String REMOTE_HOST = "127.0.0.1";
private static final Integer LOCAL_PORT = 8988;
private static final Integer REMOTE_PORT = 27017; // Default mongodb port

// ssh connection info
private static final String SSH_USER = "<username>";
private static final String SSH_PASSWORD = "<password>";
private static final String SSH_HOST = "<remote host>";
private static final Integer SSH_PORT = 22;

private static Session sshSession;

public static void main(String[] args) {
try {
    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking", "no");
    JSch jsch = new JSch();
    sshSession = null;
    sshSession = jsch.getSession(SSH_USER, SSH_HOST, SSH_PORT);
    sshSession.setPassword(SSH_PASSWORD);
    sshSession.setConfig(config);
    sshSession.connect();
    sshSession.setPortForwardingL(LOCAL_PORT, REMOTE_HOST, REMOTE_PORT);

    MongoClient mongoClient = new MongoClient(LOCAL_HOST, LOCAL_PORT);
    mongoClient.setReadPreference(ReadPreference.nearest());
    MongoCursor<String> dbNames = mongoClient.listDatabaseNames().iterator();
    while (dbNames.hasNext()) {
    System.out.println(dbNames.next());
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {
    sshSession.delPortForwardingL(LOCAL_PORT);
    sshSession.disconnect();
}
}

这段代码在运行时,已经可以工作了。连接到SSH服务器很好,但连接到它后面的Mongo数据库不起作用,并返回此错误:

INFO: Exception in monitor thread while connecting to server localhost:8988
com.mongodb.MongoSocketReadException: Prematurely reached end of stream
    at com.mongodb.connection.SocketStream.read(SocketStream.java:88)
    at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:491)
    at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:221)
    at com.mongodb.connection.CommandHelper.receiveReply(CommandHelper.java:134)
    at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:121)
    at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32)
    at com.mongodb.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:83)
    at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:43)
    at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
    at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127)
    at java.lang.Thread.run(Unknown Source)

我尝试通过以下命令行来完成这个任务:

$ ssh <user>@<host> -p 22 -X -C
$ <enter requested password>
<user>@<host>$ mongo
<user>@<host>$ MongoDB shell version: 2.6.10
<user>@<host>$ connecting to: test

看起来这个方法可行。我不知道为什么Java代码(做了差不多相同的事情)不能工作。


2
MongoDB是否在SSH服务器主机上运行?您能否在SSH服务器主机上运行“netstat -an | grep 27071”并编辑您的问题以包括输出?我想确切地看到MongoDB如何侦听连接。 - Kenster
1
我设法让它工作了(试图将端口转发到“localhost”而不是“127.0.0.1”,更改后修复了它) 编辑:我想服务器在特定情况下监听localhost而不是127.0.0.1,所以我想这也回答了您的问题Kenster。 - David V
2
通常情况下,对于不是常量的变量,您不应该使用全大写字母。SSH_SESSION不是一个常量,您可以改变它。不过很高兴您已经让它工作了。 - Carson Graham
7
你应该将问题恢复到原来的状态,并将解决方案发布为答案。 - OrangeDog
4
@DavidV 请回答您自己的问题并接受它,这样我的未回答搜索中就不会再出现这个问题了 :) - Alexandre Juma
显示剩余3条评论
2个回答

0

我成功让它工作了(尝试将端口转发到“localhost”而不是“127.0.0.1”,更改后修复了问题)编辑:我猜服务器正在专门侦听localhost而不是127.0.0.1


-3

这段代码已经成功运行,但主要问题是您的MongoDB已停止。请检查MongoDB实例是否正在运行。

sudo systemctl status mongod

如果它没有运行

sudo systemctl start mongod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接