MongoDB "no SNI name sent" 来自 heroku java 应用程序的错误

MongoDB "no SNI name sent" error from heroku java application

我按照 this tutorial 将示例应用程序部署到 Heroku。我刚刚在 MyResource class 中添加了以下方法,并从中返回了结果,而不是从 getIt() 方法中返回了 "Hello World" 。我正在连接到 atlas 免费层集群:

static String getMessage() {
        MongoClient mongoClient = new MongoClient(new MongoClientURI("mongodb://<USER>:<PASSWORD>@cluster0-shard-00-00-2lbue.mongodb.net:27017,cluster0-shard-00-01-2lbue.mongodb.net:27017,cluster0-shard-00-02-2lbue.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin"));
        DB database = mongoClient.getDB("mastery");
        DBCollection collection = database.getCollection("summary");

        DBObject query = new BasicDBObject("_id", new ObjectId("5c563fa2645d6b444c018dcb"));
        DBCursor cursor = collection.find(query);

        return (String)cursor.one().get("message");
    }

这是我正在使用的驱动程序:

<dependency>
      <groupId>org.mongodb</groupId>
      <artifactId>mongodb-driver</artifactId>
      <version>3.9.1</version>
</dependency>

这是我的导入:

import com.mongodb.*;

该应用程序在我的本地系统中运行良好。但是当我将应用程序部署到 Heroku 并点击服务时,我遇到了以下错误:

INFO: Exception in monitor thread while connecting to server cluster0-shard-00-01-2lbue.mongodb.net:27017
com.mongodb.MongoCommandException: Command failed with error 8000 (AtlasError): 'no SNI name sent, make sure using a MongoDB 3.4+ driver/shell.' on server cluster0-shard-00-01-2lbue.mongodb.net:27017. The full response is { "ok" : 0, "errmsg" : "no SNI name sent, make sure using a MongoDB 3.4+ driver/shell.", "code" : 8000, "codeName" : "AtlasError" }
at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:179)
at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:299)
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:255)
at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:83)
at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:33)
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:106)
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:63)
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:127)
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117)
at java.lang.Thread.run(Thread.java:748)

这个 SNI 名称是什么?我可以理解驱动程序可以从我的机器上获取它,但不能从 Heroku 机器上获取。但是我对如何解决这个问题一无所知!有没有办法配置 Heroku 以在驱动程序要求时显示 SNI 名称?我们可以从 Heroku 的某个地方手动获取这个值并将其直接提供给 MongoDB 驱动程序吗?感谢您的帮助。

编辑:turned out that the client mentions the SNI name of the server it wishes to connect to as part of TLS security. And there seems to be a way to manually indicate the name in python driver。有什么方法可以从 java 做到这一点吗?仍然困惑为什么当 运行 在本地应用程序时这不是问题。

我用来连接集群的代码原来是错误的。我按照 docs 的指示进行操作,它提到了这一点:

To connect to an Atlas M0 (Free Tier) cluster, you must use Java version 8 or greater and use a Java driver version that supports MongoDB 3.4.

所以我在 system.properties 文件中将 java 版本更改为 1.8

java.runtime.version=1.8

之前设置为 1.7。我还收到了关于我使用的一种方法的弃用警告。所以我再次按照 docs 使用最新的代码,它非常有效。

这里真正的收获是每次都要参考官方文档:)