【发布时间】:2022-02-23 19:15:08
【问题描述】:
我在解决如何连接到副本集方面遇到了一些麻烦 - 我需要 .watch() 收集事件,这需要一个副本集 - 请参阅:MongoDB watch() to observe change in Database with NodeJS and Mongoose(我也遵循了这个答案,没有工作 - 见这个问题的底部)
这是我的设置:
- nodejs express api + mongoose
- 我的主要“管理员”mongo db(名为
DEV) - 3 个 mongo 节点用于副本设置
我已经用这个 sn-p 用 docker-compose 设置了 3 个 mongo 节点:
version: "3"
services:
mongo0:
hostname: mongo0
container_name: mongo0
image: mongo:latest
expose:
- 30000
ports:
- 30000:30000
volumes:
- mongodb_repl_data1:/data/db
restart: always
command: "--bind_ip_all --replSet rs0 --port 30000"
mongo1:
hostname: mongo1
container_name: mongo1
image: mongo:latest
expose:
- 30001
ports:
- 30001:30001
volumes:
- mongodb_repl_data2:/data/db
restart: always
command: "--bind_ip_all --replSet rs0 --port 30001"
mongo2:
hostname: mongo2
container_name: mongo2
image: mongo:latest
expose:
- 30002
ports:
- 30002:30002
volumes:
- mongodb_repl_data3:/data/db
restart: always
command: "--bind_ip_all --replSet rs0 --port 30002"
volumes:
mongodb_repl_data1:
mongodb_repl_data2:
mongodb_repl_data3:
运行良好,我可以docker exec -it <container> mongo --port <port> 进入所有容器上的 mongo shell。
我在本地的 27017 端口有我的主要“管理员”mongo db。
我正在尝试像这样连接到他们:
await mongoose.connect("mongodb://localhost:30000,localhost:30001,localhost:30002,localhost:27017/DEV?replicaSet=rs0", {
useNewUrlParser: true,
useUnifiedTopology: true
})
当我跑的时候,它挂在这个connect()上,然后抛出:
Failed to inititate mongo connection: MongooseServerSelectionError: getaddrinfo ENOTFOUND mongo0
at NativeConnection.Connection.openUri (/Users/zac/Projects/score/app/application/server/node_modules/mongoose/lib/connection.js:821:32)
at /Users/zac/Projects/score/app/application/server/node_modules/mongoose/lib/index.js:342:10
at /Users/zac/Projects/score/app/application/server/node_modules/mongoose/lib/helpers/promiseOrCallback.js:31:5
at new Promise (<anonymous>)
at promiseOrCallback (/Users/zac/Projects/score/app/application/server/node_modules/mongoose/lib/helpers/promiseOrCallback.js:30:10)
at Mongoose.connect (/Users/zac/Projects/score/app/application/server/node_modules/mongoose/lib/index.js:341:10)
at Object.exports.default (/Users/zac/Projects/score/app/application/server/dist/submodules/connectDb.js:13:34)
at start (/Users/zac/Projects/score/app/application/server/dist/index.js:31:34)
at Object.<anonymous> (/Users/zac/Projects/score/app/application/server/dist/index.js:47:1)
at Module._compile (internal/modules/cjs/loader.js:1075:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1096:10)
at Module.load (internal/modules/cjs/loader.js:940:32)
at Function.Module._load (internal/modules/cjs/loader.js:781:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
at internal/main/run_main_module.js:17:47 {
reason: TopologyDescription {
type: 'ReplicaSetNoPrimary',
setName: 'rs0',
maxSetVersion: 1,
maxElectionId: 7fffffff0000000000000001,
servers: Map(3) {
'mongo0:30000' => [ServerDescription],
'mongo1:30001' => [ServerDescription],
'mongo2:30002' => [ServerDescription]
},
stale: false,
compatible: true,
compatibilityError: null,
logicalSessionTimeoutMinutes: null,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
commonWireVersion: 9
}
}
在 mongo 节点中,我确实这样做了:
config={"_id":"rs0","members":[{"_id":0,"host":"mongo0:30000"},{"_id":1,"host":"mongo1:30001"},{"_id":2,"host":"mongo2:30002"}]}
rs.initiate(config);
返回成功:
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1609794399, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1609794399, 1)
}
如果我这样做rs.status():
rs0:SECONDARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2021-01-04T21:06:53.009Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"votingMembersCount" : 3,
"writableVotingMembersCount" : 3,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1609794412, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2021-01-04T21:06:52.570Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1609794412, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2021-01-04T21:06:52.570Z"),
"appliedOpTime" : {
"ts" : Timestamp(1609794412, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1609794412, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2021-01-04T21:06:52.570Z"),
"lastDurableWallTime" : ISODate("2021-01-04T21:06:52.570Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1609794411, 3),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2021-01-04T21:06:51.027Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1609794399, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2021-01-04T21:06:51.051Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2021-01-04T21:06:52.545Z")
},
"members" : [
{
"_id" : 0,
"name" : "mongo0:30000",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1485,
"optime" : {
"ts" : Timestamp(1609794412, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2021-01-04T21:06:52Z"),
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1609794411, 1),
"electionDate" : ISODate("2021-01-04T21:06:51Z"),
"configVersion" : 1,
"configTerm" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "mongo1:30001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 13,
"optime" : {
"ts" : Timestamp(1609794399, 1),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(1609794399, 1),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("2021-01-04T21:06:39Z"),
"optimeDurableDate" : ISODate("2021-01-04T21:06:39Z"),
"lastHeartbeat" : ISODate("2021-01-04T21:06:51.038Z"),
"lastHeartbeatRecv" : ISODate("2021-01-04T21:06:52.549Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 1,
"configTerm" : 0
},
{
"_id" : 2,
"name" : "mongo2:30002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 13,
"optime" : {
"ts" : Timestamp(1609794399, 1),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(1609794399, 1),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("2021-01-04T21:06:39Z"),
"optimeDurableDate" : ISODate("2021-01-04T21:06:39Z"),
"lastHeartbeat" : ISODate("2021-01-04T21:06:51.040Z"),
"lastHeartbeatRecv" : ISODate("2021-01-04T21:06:52.551Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 1,
"configTerm" : 0
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1609794412, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1609794412, 1)
}
没有 Docker,我尝试像这样使用mongodb-topology-manager:
提供于:MongoDB watch() to observe change in Database with NodeJS and Mongoose
import { ReplSet } from 'mongodb-topology-manager';
export default async () => {
// Starts a 3-node replica set on ports 31000, 31001, 31002, replica set
// name is "rs0".
const replSet = new ReplSet('mongod', [{ options: { port: 31000, dbpath: `${__dirname}/data/db/31000`, bind_ip: 'localhost' } },
{ options: { port: 31000, dbpath: `${__dirname}/data/db/31001`, bind_ip: 'localhost' } },
{ options: { port: 31001, dbpath: `${__dirname}/data/db/31001`, bind_ip: 'localhost' } },
{ options: { port: 31002, dbpath: `${__dirname}/data/db/31002`, bind_ip: 'localhost' } }
], { replSet: 'rs0' });
try {
console.log("rep set discovering...");
await replSet.discover()
console.log("rep set purging...");
await replSet.purge();
console.log("rep set starting...");
await replSet.start();
console.log("rep set done.");
} catch (err) {
console.error("Failed to start replica sets:", err);
}
}
但如果我运行它,它总是挂在replSet.start() 上并且从不做任何事情,只是永远挂起。 db 路径存在,其他地方不使用端口。
rep set discovering...
rep set purging...
rep set starting...
简单地说,我如何正确启动一个 mongodb repl 集并通过 mongoose 连接到它?如果我需要在本地(不在 Docker 中)设置 repl,我该如何使用我的一个本地 mongodb 实例来做到这一点(这样我就可以使用命令$ mongo 或$ mongod 访问它们,而不是通过 docker)?
任何帮助将不胜感激
【问题讨论】:
-
getaddrinfo ENOTFOUND mongo0看起来像是名称解析错误
标签: node.js mongodb docker mongoose replicaset