使用 Java 连接到在 Docker 内运行的 MongoDB 副本集 (Windows)

2024-02-25

我想使用 docker 设置 MongoDB 副本集。设置似乎没问题,但我无法使用 Java 应用程序连接到集群。我在 Windows 10 上运行 Docker 版本 17.06.0-ce,并使用 VirtualBox 作为驱动程序。

我按照本教程中的说明进行操作:http://www.sohamkamani.com/blog/2016/06/30/docker-mongo-replica-set/ http://www.sohamkamani.com/blog/2016/06/30/docker-mongo-replica-set/

因此,我首先在 docker 中创建了 my-mongo-cluster 网络,并使用以下命令运行 3 个容器:

$ docker run --name mongo1 -d --net mongo-cluster -p 9042:27017 mongo:3.6.0 mongod --replSet my-mongo-set
$ docker run --name mongo2 -d --net mongo-cluster -p 9142:27017 mongo:3.6.0 mongod --replSet my-mongo-set
$ docker run --name mongo3 -d --net mongo-cluster -p 9242:27017 mongo:3.6.0 mongod --replSet my-mongo-set

然后我连接到 mongo1 容器并使用以下配置设置副本集:

config = {"_id" : "my-mongo-set", "members" : [{"_id" : 0,"host" : "mongo1:27017"},{"_id" : 1,"host" : "mongo2:27017"},{"_id" : 2,"host" : "mongo3:27017"}]}
rs.initiate(config)

这似乎工作得很好。从 mongo1 容器的日志中我可以看出,所有容器都相互连接。

现在我正在尝试从我的 Java 应用程序连接到副本集。我使用的是 mongodb 驱动程序版本 3.6.0。 这是我用来连接到在 docker 中运行的副本集的代码:

List<ServerAddress> serverAddresses = new ArrayList<ServerAddress>();
serverAddresses.add(new ServerAddress(InetAddress.getByName("192.168.99.100"), 9042));
serverAddresses.add(new ServerAddress(InetAddress.getByName("192.168.99.100"), 9142));
serverAddresses.add(new ServerAddress(InetAddress.getByName("192.168.99.100"), 9242));

MongoClient client = new MongoClient(serverAddresses);

这是日志输出(最后的 MongoSocketException 也出现在 mongo1:27017 和 mongo2:27017 中):

Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Cluster created with settings {hosts=[192.168.99.100:9042, 192.168.99.100:9142, 192.168.99.100:9242], mode=MULTIPLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Adding discovered server 192.168.99.100:9042 to client view of cluster
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Adding discovered server 192.168.99.100:9142 to client view of cluster
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Adding discovered server 192.168.99.100:9242 to client view of cluster
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Cluster description not yet available. Waiting for 30000 ms before timing out
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Opened connection [connectionId{localValue:2, serverValue:5}] to 192.168.99.100:9142
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Opened connection [connectionId{localValue:1, serverValue:14}] to 192.168.99.100:9042
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Opened connection [connectionId{localValue:3, serverValue:5}] to 192.168.99.100:9242
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Monitor thread successfully connected to server with description ServerDescription{address=192.168.99.100:9242, type=REPLICA_SET_SECONDARY, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 6, 0]}, minWireVersion=0, maxWireVersion=6, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=5002651, setName='my-mongo-set', canonicalAddress=mongo3:27017, hosts=[mongo3:27017, mongo2:27017, mongo1:27017], passives=[], arbiters=[], primary='mongo1:27017', tagSet=TagSet{[]}, electionId=null, setVersion=1, lastWriteDate=Wed Dec 27 21:36:00 CET 2017, lastUpdateTimeNanos=440549516217673}
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Monitor thread successfully connected to server with description ServerDescription{address=192.168.99.100:9142, type=REPLICA_SET_SECONDARY, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 6, 0]}, minWireVersion=0, maxWireVersion=6, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=5542139, setName='my-mongo-set', canonicalAddress=mongo2:27017, hosts=[mongo3:27017, mongo2:27017, mongo1:27017], passives=[], arbiters=[], primary='mongo1:27017', tagSet=TagSet{[]}, electionId=null, setVersion=1, lastWriteDate=Wed Dec 27 21:36:00 CET 2017, lastUpdateTimeNanos=440549516254709}
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Monitor thread successfully connected to server with description ServerDescription{address=192.168.99.100:9042, type=REPLICA_SET_PRIMARY, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 6, 0]}, minWireVersion=0, maxWireVersion=6, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=4113767, setName='my-mongo-set', canonicalAddress=mongo1:27017, hosts=[mongo3:27017, mongo2:27017, mongo1:27017], passives=[], arbiters=[], primary='mongo1:27017', tagSet=TagSet{[]}, electionId=7fffffff0000000000000001, setVersion=1, lastWriteDate=Wed Dec 27 21:36:00 CET 2017, lastUpdateTimeNanos=440549515190458}
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Discovered cluster type of REPLICA_SET
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Adding discovered server mongo3:27017 to client view of cluster
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Adding discovered server mongo2:27017 to client view of cluster
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Adding discovered server mongo1:27017 to client view of cluster
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Canonical address mongo2:27017 does not match server address.  Removing 192.168.99.100:9142 from client view of cluster
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Server 192.168.99.100:9242 is no longer a member of the replica set.  Removing from client view of cluster.
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Server 192.168.99.100:9042 is no longer a member of the replica set.  Removing from client view of cluster.
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Canonical address mongo1:27017 does not match server address.  Removing 192.168.99.100:9042 from client view of cluster
Dez 27, 2017 9:36:07 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: No server chosen by com.mongodb.Mongo$4@67784306 from cluster description ClusterDescription{type=REPLICA_SET, connectionMode=MULTIPLE, serverDescriptions=[ServerDescription{address=192.168.99.100:9242, type=UNKNOWN, state=CONNECTING}, ServerDescription{address=mongo3:27017, type=UNKNOWN, state=CONNECTING}, ServerDescription{address=mongo2:27017, type=UNKNOWN, state=CONNECTING}, ServerDescription{address=mongo1:27017, type=UNKNOWN, state=CONNECTING}, ServerDescription{address=192.168.99.100:9042, type=UNKNOWN, state=CONNECTING}]}. Waiting for 30000 ms before timing out
Dez 27, 2017 9:36:09 PM com.mongodb.diagnostics.logging.JULLogger log
INFORMATION: Exception in monitor thread while connecting to server mongo3:27017
com.mongodb.MongoSocketException: mongo3
at com.mongodb.ServerAddress.getSocketAddress(ServerAddress.java:188)
at com.mongodb.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:59)
at com.mongodb.connection.SocketStream.open(SocketStream.java:57)
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:126)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:114)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.UnknownHostException: mongo3
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323)
at java.net.InetAddress.getAllByName0(InetAddress.java:1276)
at java.net.InetAddress.getAllByName(InetAddress.java:1192)
at java.net.InetAddress.getAllByName(InetAddress.java:1126)
at java.net.InetAddress.getByName(InetAddress.java:1076)
at com.mongodb.ServerAddress.getSocketAddress(ServerAddress.java:186)
... 5 more

最后我通过阅读以下内容找到了解决方案:

https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#clients-use-the-hostnames-listed-in-the-副本集配置不是种子列表 https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#clients-use-the-hostnames-listed-in-the-replica-set-config-not-the-seed-list

最后一句话很重要:“总之,为了支持副本集的关键功能,我们要求可以从客户端访问副本集配置中使用的主机名。”

因此,这意味着配置中的主机名必须从外部可见/可访问。但由于我在 Windows 上使用 VirtualBox 运行 Docker,MongoClient 只能看到虚拟机的 IP,而无法处理 mongo1、mongo2、mongo3(分别是容器的内部 IP)。

解决方案是将主机名添加到主机文件中(在 Windows 中位于 C:/Windows/System32/drivers/etc/hosts):

192.168.99.100 mongo1 192.168.99.100 mongo2 192.168.99.100 mongo3

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Java 连接到在 Docker 内运行的 MongoDB 副本集 (Windows) 的相关文章

随机推荐