【问题标题】:mongoose connection to Replica Sets always fails猫鼬与副本集的连接总是失败
【发布时间】: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


【解决方案1】:

我遇到了同样的问题,过去一周一直在尝试寻找解决方案。但是我找到的解决方案非常琐碎。

config={"_id":"rs0","members":[{"_id":0,"host":"mongo0:30000"},{"_id":1,"host":"mongo1:30001"},{"_id":2,"host":"mongo2:30002"}]}

我已将主机中的“mongo0”等更改为我的内部 IP(即 192.168.1.5 等)。好像解决了这个问题。

【讨论】:

    【解决方案2】:

    有一种方法可以通过部署另一个 docker 来自动执行配置,以执行应用该配置的脚本。所以我可以用这个文件创建一个单实例非复制模式:

    • docker-compose.yml
    version: "3"
    services:
      mongo-setup:
        image: mongo
        restart: on-failure
        volumes:
          - ./scripts:/scripts
        entrypoint: [ "/scripts/setup-replicaset.sh" ]
        depends_on:
          - mongodb01
      mongodb01:
        image: "mongo"
        ports:
          - "27017:27017"
        volumes:
          - mongo-data:/data/db
        command: "--bind_ip_all --replSet rs0"
    volumes:
     mongo-data:
        driver: local
    
    • 脚本/setup-replicaset.sh
    #!/bin/bash
    
    MONGODB1=mongodb01
    
    echo "**********************************************" ${MONGODB1}
    echo "Waiting for startup.."
    until curl http://${MONGODB1}:27017/serverStatus\?text\=1 2>&1 | grep uptime | head -1; do
      echo '.'
      sleep 1
    done
    
    echo SETUP.sh time now: `date +"%T" `
    mongo --host ${MONGODB1}:27017 <<EOF
    var cfg = {
        "_id": "rs0",
        "protocolVersion": 1,
        "version": 1,
        "members": [
            {
                "_id": 0,
                "host": "${MONGODB1}:27017",
                "priority": 2
            }
        ],settings: {chainingAllowed: true}
    };
    rs.initiate(cfg, { force: true });
    rs.reconfig(cfg, { force: true });
    rs.slaveOk();
    db.getMongo().setReadPref('nearest');
    db.getMongo().setSlaveOk();
    EOF
    

    运行此 docker-compose 后,您可以通过 localhost 正常连接 mongoose。

    【讨论】:

      猜你喜欢
      • 2021-10-25
      • 2016-01-15
      • 2018-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多