如何通过 Java 驱动程序正确连接到 Atlas M0(免费层)集群?

Posted

技术标签:

【中文标题】如何通过 Java 驱动程序正确连接到 Atlas M0(免费层)集群?【英文标题】:How to connect to Atlas M0 (Free Tier) cluster correctly via Java driver? 【发布时间】:2018-11-27 17:06:30 【问题描述】:

尝试使用MongoDB version 3.6通过Java驱动连接Atlas集群。

所以,我是这样写的:

 MongoClientURI uri = new MongoClientURI("mongodb+srv://admin:mypassword@cluster0-ox90k.mongodb.net/test?retryWrites=true");
 MongoClient mongoClient = new MongoClient(uri);

在这种情况下,错误是:

java.lang.IllegalArgumentException: The connection string is invalid. Connection strings must start with 'mongodb://'
    at com.mongodb.ConnectionString.<init>(ConnectionString.java:203)
    at com.mongodb.MongoClientURI.<init>(MongoClientURI.java:176)
    at com.mongodb.MongoClientURI.<init>(MongoClientURI.java:158)
    at project.Bot.check(Bot.java:30)
    at project.Bot.onUpdateReceived(Bot.java:104)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at org.telegram.telegrambots.generics.LongPollingBot.onUpdatesReceived(LongPollingBot.java:27)
    at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$HandlerThread.run(DefaultBotSession.java:309)

当程序以 sn -p 启动时使用 MongoDB 版本 3.6 或更高版本不带+srv

MongoClientURI uri = new MongoClientURI("mongodb://admin1:mypassword@cluster0-ox90k.mongodb.net/test?retryWrites=true");
MongoClient mongoClient = new MongoClient(uri);

我收到一个错误:

com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelectorreadPreference=primary. Client view of cluster state is type=UNKNOWN, servers=[address=cluster0.mongodb.net:27017, type=UNKNOWN, state=CONNECTING, exception=com.mongodb.MongoSocketException: cluster0.mongodb.net, caused by java.net.UnknownHostException: cluster0.mongodb.net]
    at com.mongodb.connection.BaseCluster.createTimeoutException(BaseCluster.java:369)
    at com.mongodb.connection.BaseCluster.selectServer(BaseCluster.java:101)
    at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:75)
    at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:71)
    at com.mongodb.binding.ClusterBinding.getReadConnectionSource(ClusterBinding.java:63)
    at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:201)
    at com.mongodb.operation.CountOperation.execute(CountOperation.java:206)
    at com.mongodb.operation.CountOperation.execute(CountOperation.java:53)
    at com.mongodb.Mongo.execute(Mongo.java:772)
    at com.mongodb.Mongo$2.execute(Mongo.java:759)
    at com.mongodb.MongoCollectionImpl.count(MongoCollectionImpl.java:185)
    at com.mongodb.MongoCollectionImpl.count(MongoCollectionImpl.java:170)
    at project.Bot.check(Bot.java:36)
    at project.Bot.onUpdateReceived(Bot.java:103)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at org.telegram.telegrambots.generics.LongPollingBot.onUpdatesReceived(LongPollingBot.java:27)
    at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$HandlerThread.run(DefaultBotSession.java:309)

在 POM 文件中我有依赖项:

        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.6.0</version>
        </dependency>

另外,当我开始mongo 时,我的数据库被添加到这个地址mongodb://127.0.0.1:27017,但我添加的集群路径不是为了这个。也许我需要写具体集群的路径或者?

Ofc,我有管理员用户。此外,我可以通过 Compass 连接到我的集群和从 shell。 mongod 进程已启动。仅当我在 IDE 中运行时才会出现此错误。可能是同样的问题here。

有谁知道如何解决这个错误?感谢您的帮助。

【问题讨论】:

将“cluster0.mongodb.net”改成准确的IP地址会有帮助吗? @y.bedrov,如果我写一个本地地址,例如?是的,我可以连接到本地地址,但我不知道,为什么 IDE 告诉我错误,可能是命令错误或需要添加一些东西。即使我尝试连接到本地地址,也会出现此错误。 【参考方案1】:

我遇到了类似的问题,通过选择 Node 驱动程序版本 2.2.12 或更高版本解决了它,它会给我一个以 'mongodb://' 开头的连接字符串

【讨论】:

【参考方案2】:

我遇到了这个问题,我检查了文档 我创建了一个这样的配置类

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig 

    public @Bean
    MongoClient mongoClient() 
        return MongoClients.create("mongodb://localhost:27017");
    

您可以将您的 uri 放在“mongodb://localhost:27017”所在的位置

https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#reference

【讨论】:

【参考方案3】:

解决了! 所以,我做了什么:

    我只尝试通过driver3.6连接到tier cluster并写了

    mongodb+srv://user:@cluster0-ox90k.mongodb.net/test?retryWrites=true

我总是收到错误: Connection strings must start with 'mongodb://'

    好的,我删除了sn-p+srv,照样写

    mongodb://user:@cluster0-ox90k.mongodb.net/test?retryWrites=true

然后再次得到错误:

com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelectorreadPreference=primary. Client view of cluster state is type=UNKNOWN, servers=[address=cluster0-ox90k.mongodb.net:27017, type=UNKNOWN, state=CONNECTING, exception=com.mongodb.MongoSocketException: cluster0-ox90k.mongodb.net, caused by java.net.UnknownHostException: cluster0-ox90k.mongodb.net]

所以,我是通过driver3.4或更早的版本写的

mongodb://user:<PASSWORD>@cluster0-shard-00-00-ox90k.mongodb.net:27017,cluster0-shard-00-01-ox90k.mongodb.net:27017,cluster0-shard-00-02-ox90k.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true

终于解决了。

注意:您可以通过将 Java 驱动程序设置为“3.4 或更高版本”从 Atlas 管理控制台获取此连接字符串。这将帮助您避免自己想出连接字符串。


更新:如果你想使用驱动3.7+,你需要写而不是格式化连接(并且避免我上面的问题)

MongoClientURI uri = new MongoClientURI("mongodb+srv://admin:mypassword@cluster0-ox90k.mongodb.net/test?retryWrites=true");
MongoClient mongoClient = new MongoClient(uri);

使用MongoClients.create() (as of the 3.7 release), 和提到的here 的另一个变体:

   MongoClient mongoClient = MongoClients.create("mongodb+srv://admin:mypassword@cluster0-ox90k.mongodb.net/test?retryWrites=true");

注意:密码不要写成mongodb://user:&lt;mypassword&gt;@...

格式为mongodb://user:mypassword@...

没有大括号&lt;&gt;

【讨论】:

【参考方案4】:

上述解决方案在当前分配中不起作用,因为我正在处理 Spring-boot 框架分配。

我有错误 Caused by: java.net.UnknownHostException: khweshacluster0.brzta.mongodb.net

要解决这个问题,我必须从下面进行配置

采用突出显示的网址 & 将以下格式的 URL 设为

spring.data.mongodb.uri=mongodb://:@

&application.properties 中的相同更新 如下,

spring.data.mongodb.uri=mongodb://username:password@khweshacluster0-shard-00-00.brzta.mongodb.net:27017,khweshacluster0-shard-00-01.brzta.mongodb.net:27017 ,khweshacluster0-shard-00-02.brzta.mongodb.net:27017/myFirstDatabase?ssl=true&replicaSet=atlas-3b1nqz-shard-0&authSource=admin&retryWrites=true&w=majority

【讨论】:

【参考方案5】:

我在尝试从我的 tomcat 应用程序连接到 MongoDB 时遇到了同样的问题。 我使用 Mongo Driver 3.12.3 与应用程序一起安装了 tomcat 9.0 和 MongoDB 4.2

Error: org.springframework.dao.DataAccessResourceFailureException: Timed out after 
30000 ms while waiting to connect. Client view of cluster state is type=UNKNOWN, 
servers=[address=@127.0.0.1:27017, type=UNKNOWN, state=CONNECTING, exception=
com.mongodb.MongoSocketException: @127.0.0.1, caused by 
java.net.UnknownHostException: @127.0.0.1]; nested exception is 
com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting to connect.
 Client view of cluster state is type=UNKNOWN, servers=[address=@127.0.0.1:27017, 
type=UNKNOWN, state=CONNECTING, exception=com.mongodb.MongoSocketException: 
@127.0.0.1, caused by java.net.UnknownHostException: @127.0.0.1]

我尝试创建示例 Java 应用程序来连接 DB,它可以工作,但是无法从 Web 应用程序连接。

因此为 DB 创建了用户并分配了角色 userAdmin,这对我有用。

Not working Conn String - mongodb://@127.0.0.1:27017/docs <br>
Working Conn string -     mongodb://docs_local:docs@127.0.0.1:27017/docs

【讨论】:

【参考方案6】:

还有一个重要的注意事项: 在这个字符串中:

MongoClientURI uri = new MongoClientURI("mongodb+srv://admin:mypassword@cluster0-ox90k.mongodb.net/test?retryWrites=true");

test ==> 是一个 Db 名称,在建立此连接之前,DB 应该存在。

【讨论】:

【参考方案7】:

这里似乎有一些问题

第一

3.6.0 不是实际加载到应用程序类路径中的 Mongo 驱动程序库;我怀疑您之前使用的是旧版本进行测试,并且最近更新了 POM?您之前使用的是 3.2.0 版本。

我怎么知道的?

我开始挖掘代码,at version 3.6.0,您提供的错误消息与第 203 行相去甚远。而且,您可以看到上面链接的代码支持+srv

回顾以前的版本,我终于在第 203 行发现了错误消息,回到 release 3.2.0。

长话短说,尝试进行 Maven 清理和重建。

如果项目刷新没有帮助,请重新启动 Eclipse 以获取新的依赖项。

第二

MongoTimeoutException: 在等待服务器时超时 30000 毫秒

这很可能是防火墙/访问控制组配置问题,因为防火墙阻止数据包到达您的 Atlas 集群。

见adding addresses to the whitelist。

【讨论】:

谢谢你,马特的详细回答!是的,我多次更改版本,但问题是一样的。我会检查你的链接,现在试图理解为什么我会收到“mongodb+srv”的第一个错误,因为我最初使用的是 3.6 版。 根据发布的错误,3.2.0 版是加载到类路径中的版本。您是从 Maven 获取这些依赖项吗?尝试删除您的~/.m2 目录并重建,这将导致重新下载所有工件。尝试检查您的类路径以查看实际加载的 jar。 是的,这个依赖是针对maven的,使用POM文件。我尝试从 IDE Eclipse 进行连接,结果类似于:INFO: Cluster created with settings hosts=[127.0.0.1:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500,但随后也出现了第二个问题。 Matt Clark,当我尝试将信息添加到集群中的数据库时,发生了第二个问题。但是我看到我的db不是在集群中添加的,而是添加到这个本地地址(我在运行mongo进程时看到的):mongodb://127.0.0.1:27017,但是在代码中指定了集群的路径。我有 M0(免费层)集群。 如果我运行本地地址而不是集群,我得到:"com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelectorreadPreference=primary. Client view of cluster state is type=UNKNOWN, servers=[address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception=com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message, caused by java.net.SocketTimeoutException: Read timed out]"

以上是关于如何通过 Java 驱动程序正确连接到 Atlas M0(免费层)集群?的主要内容,如果未能解决你的问题,请参考以下文章

无法将 Mongoose 连接到 Atlas

节点/快速应用程序无法使用mongoose连接到Mongodb Atlas

Heroku 没有连接到 Mongo Atlas DB?

Heroku 没有连接到 Mongo Atlas DB?

如何将Django ORM连接到mongo atlas?

Kubernetes node.js 容器无法连接到 MongoDB Atlas