我成功地使用三个容器创建了docker副本集:
CONTAINER ID IMAGE PORTS NAMES
b530275d1958 mongo 0.0.0.0:30003->27017/tcp mongo3
dca4fa2d6f93 mongo 0.0.0.0:30002->27017/tcp mongo2
0b4823661cf1 mongo 0.0.0.0:27017->27017/tcp mongo1
此外,副本集已成功配置:
rs0:PRIMARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2018-01-08T20:57:30.395Z"),
"myState" : 1,
"term" : NumberLong(16),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1515445046, 1),
"t" : NumberLong(16)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1515445046, 1),
"t" : NumberLong(16)
},
"appliedOpTime" : {
"ts" : Timestamp(1515445046, 1),
"t" : NumberLong(16)
},
"durableOpTime" : {
"ts" : Timestamp(1515445046, 1),
"t" : NumberLong(16)
}
},
"members" : [
{
"_id" : 0,
"name" : "mongo1:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 898,
"optime" : {
"ts" : Timestamp(1515445046, 1),
"t" : NumberLong(16)
},
"optimeDate" : ISODate("2018-01-08T20:57:26Z"),
"electionTime" : Timestamp(1515444174, 1),
"electionDate" : ISODate("2018-01-08T20:42:54Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "mongo2:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 877,
"optime" : {
"ts" : Timestamp(1515445046, 1),
"t" : NumberLong(16)
},
"optimeDurable" : {
"ts" : Timestamp(1515445046, 1),
"t" : NumberLong(16)
},
"optimeDate" : ISODate("2018-01-08T20:57:26Z"),
"optimeDurableDate" : ISODate("2018-01-08T20:57:26Z"),
"lastHeartbeat" : ISODate("2018-01-08T20:57:29.056Z"),
"lastHeartbeatRecv" : ISODate("2018-01-08T20:57:30.324Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "mongo1:27017",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "mongo3:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 871,
"optime" : {
"ts" : Timestamp(1515445046, 1),
"t" : NumberLong(16)
},
"optimeDurable" : {
"ts" : Timestamp(1515445046, 1),
"t" : NumberLong(16)
},
"optimeDate" : ISODate("2018-01-08T20:57:26Z"),
"optimeDurableDate" : ISODate("2018-01-08T20:57:26Z"),
"lastHeartbeat" : ISODate("2018-01-08T20:57:29.055Z"),
"lastHeartbeatRecv" : ISODate("2018-01-08T20:57:29.506Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "mongo1:27017",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1515445046, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1515445046, 1),
"signature" : {
"hash" : BinData(0,"c3aBSVWElstPhnBx3c5NysBfdmk="),
"keyId" : NumberLong("6504664228182360065")
}
}
}
重要的是要注意,它是端口
27017
,30002
和30003
上的仅一个VM连接但是,当我的PHP应用程序使用我附加到它的mongo DSN字符串连接到它时,似乎出现了问题
mongodb://<username>:<pass>@172.31.6.177:27017,172.31.6.177:30002,172.31.6.177:30003/opsserver-main?replicaSet=rs0&authSource=admin"
我的PHP应用程序中出现错误:
[Doctrine\MongoDB\Exception\ResultException]
No suitable servers found: `serverSelectionTimeoutMS` expired: [connection timeout calling i
smaster on '172.31.6.177:27017'] [connection timeout calling ismaster on 'mongo1:27017'] [co
nnection timeout calling ismaster on 'mongo2:27017'] [connection timeout calling ismaster on
'mongo3:27017']
我很奇怪它知道容器名称,或者至少尝试连接到它。我究竟做错了什么?
最佳答案
这是因为在docker网络内部,容器mongo1
,mongo2
和mongo3
可以相互找到。但是,主机系统不知道这些名称,因此您的应用程序无法连接到整个集合。
您可以尝试从主机系统ping mongo1
,其中应该显示Unknown host
。
解决此问题的最简单方法是更改副本集配置中的主机名(使用rs.initiate(...)
启动副本集时使用的主机名),例如:
mongo1:27017
-> <your local hostname>:27017
mongo2:27017
-> <your local hostname>:30002
mongo3:27017
-> <your local hostname>:30003
将
<your local hostname>
替换为hostname -f
命令的输出。这样,您的本地主机可以找到所有副本集节点,而所有副本集节点仍可以通过本地主机的端口映射找到彼此。
关于mongodb - MongoDB Docker副本集-应用程序连接超时,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48158054/