简体   繁体   English

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

[英]Connect to MongoDB Replica Set running inside Docker with Java (Windows)

I want to set up a MongoDB replica set with docker. 我想用docker设置一个MongoDB副本集。 The setup seems to be fine but I'm not able to connect to the cluster with my Java-app. 设置似乎很好,但我无法使用我的Java应用程序连接到群集。 I'm running Docker version 17.06.0-ce on Windows 10 with VirtualBox as driver. 我在Windows 10上使用VirtualBox作为驱动程序运行Docker版本17.06.0-ce。

I followed the instructions from this tutorial: http://www.sohamkamani.com/blog/2016/06/30/docker-mongo-replica-set/ 我按照本教程中的说明操作: http//www.sohamkamani.com/blog/2016/06/30/docker-mongo-replica-set/

So I first created the my-mongo-cluster network in docker and run 3 containers with the following commands: 所以我首先在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

Then I connect to the mongo1 container and set up the replica set with the following config: 然后我连接到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)

This seems to work just fine. 这似乎工作得很好。 As I can tell from the logs of the mongo1 container all containers are connected to each other. 正如我从mongo1容器的日志中可以看出的那样,所有容器都相互连接。

Now I'm trying to connect from my Java-app to the replica set. 现在我正在尝试从我的Java应用程序连接到副本集。 I'm using the mongodb-driver version 3.6.0. 我正在使用mongodb-driver 3.6.0版。 This is the code I'm using to connect to the replica set running in docker: 这是我用来连接到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);

And this is the log-output (the MongoSocketException at the end also appears for mongo1:27017 and mongo2:27017): 这是日志输出(最后的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

Finally I found the solution by reading this: 最后我通过阅读这个找到了解决方案:

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 https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#clients-use-the-hostnames-listed-in-the-副本集-配置-不的种子列表

The last sentence is important: "In conclusion, to support key features of replica sets, we require that the hostnames used in a replica set config are reachable from the client." 最后一句很重要: “总之,为了支持副本集的关键功能,我们要求从副客户端访问副本集配置中使用的主机名。”

So this means that the hostnames in the config have to be visible/accessible from outside. 所以这意味着配置中的主机名必须从外部可见/可访问。 But since I'm running Docker on Windows with VirtualBox the MongoClient only can see the IP of my VM and can't handle mongo1, mongo2, mongo3 (respectively the internal IPs of the containers). 但是由于我在Windows上使用VirtualBox运行Docker,MongoClient只能看到我的VM的IP,无法处理mongo1,mongo2,mongo3(分别是容器的内部IP)。

The solution was to add the hostnames to the hosts-file (in Windows located at C:/Windows/System32/drivers/etc/hosts): 解决方案是将主机名添加到hosts-file(位于C:/ Windows / System32 / drivers / etc / hosts的Windows中):

192.168.99.100 mongo1 192.168.99.100 mongo2 192.168.99.100 mongo3

Adding the hostnames to the hosts file did not work for me. 将主机名添加到hosts文件对我来说不起作用。 I think if all hostnames refers to the same host IP (eg 127.0.0.1), it's not going to work if all docker ports are the same (eg 27017). 我想如果所有主机名都引用相同的主机IP(例如127.0.0.1),如果所有的docker端口都相同(例如27017),它就不会起作用。 The replica set is composed by mongo1:27017, mongo2:27017 and mongo3:27017 inside docker. 副本集由mongo1:27017, mongo2:27017 and mongo3:27017 Outside docker it corresponds to 127.0.0.1:27017, 127.0.0.1:27017 and 127.0.0.1:27017 which won't work. 在docker之外,它对应于127.0.0.1:27017, 127.0.0.1:27017 and 127.0.0.1:27017 ,这是行不通的。 To fix the issue I had to set a different port for each node. 要解决此问题,我必须为每个节点设置不同的端口。

docker network create mongo-cluster
docker run --name mongo1 -d --net mongo-cluster -p 9042:9042 mongo:3.6 mongod --replSet docker-rs --port 9042
docker run --name mongo2 -d --net mongo-cluster -p 9142:9142 mongo:3.6 mongod --replSet docker-rs --port 9142
docker run --name mongo3 -d --net mongo-cluster -p 9242:9242 mongo:3.6 mongod --replSet docker-rs --port 9242
docker exec -it mongo1 mongo --port 9042
config = {"_id" : "docker-rs", "members" : [{"_id" : 0,"host" : "mongo1:9042"},{"_id" : 1,"host" : "mongo2:9142"},{"_id" : 2,"host" : "mongo3:9242"}]}
rs.initiate(config)
rs.status() 

and finally add the hostnames to the hosts file 最后将主机名添加到hosts文件中

127.0.0.1 mongo1 mongo2 mongo3

问题是您的副本集节点在端口9x42外面看到,但那些节点内部(已配置)地址是27017.两者必须相同。因此,当您启动mongod您必须为--port参数指定相同的端口号使用的是什么在集装箱外面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Docker for mac - 无法从容器内部连接到在主机上运行的 mongo 副本集 - Docker for mac - Not able to connect to a mongo replica set running on host from inside the container 连接到在Docker中运行的mongodb - Connect to mongodb running inside Docker 从另一个 docker 容器连接到 Mongodb 副本集失败 - Connect to Mongodb replica set from another docker container failed Spring Boot连接到Mongo容器运行的MongoDB副本集 - Spring boot connect to MongoDB replica set of mongo container running Spring引导连接到使用Arbiter运行的MongoDB副本集 - Spring boot connect to MongoDB replica set running with an Arbiter 在 .yml 文件中实现 docker mongodb 副本集配置设置 - Implement docker mongodb replica set config settings inside .yml file Mongodb与在docker组成的副本集合 - Mongodb with replica set in docker compose 无法连接到mongodb副本集 - Cannot connect to mongodb replica set MongoDB shell 4.0.3 Windows 无法连接到 MongoDB 副本集:SSLHandshakeFailed: QueryContextAttributes for connection info failed - MongoDB shell 4.0.3 Windows cannot connect to MongoDB replica set: SSLHandshakeFailed: QueryContextAttributes for connection info failed 使用Docker 1.12服务设置的Mongodb副本 - Mongodb replica set with Docker 1.12 services
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM