【问题标题】:NodeJS cannot connect to mongo replicat setNodeJS 无法连接到 mongo 副本集
【发布时间】:2021-10-30 14:26:09
【问题描述】:

我在 docker 上为 mongo 创建了 3 个容器:

docker pull mongo

docker network create mongo-cluster

docker run -d -p 27017:27017 --name m1 --net mongo-cluster mongo mongod --replSet mongo-rs

docker run -d -p 27018:27017 --name m2 --net mongo-cluster mongo mongod --replSet mongo-rs

docker run -d -p 27019:27017 --name m3 --net mongo-cluster mongo mongod --replSet mongo-rs

并设置副本集:

docker exec -it m1 mongo

config = { "_id" : "mongo-rs", "members" : [ { "_id" : 0, "host" : "m1:27017" }, { "_id" : 1, "host" : "m2:27017" }, { "_id" : 2, "host" : "m3:27017" }] }

rs.initiate(config)

mongo-rs:PRIMARY>

> db.pets.insert({name : 'pet'})
WriteResult({ "nInserted" : 1 })

m1 是主要的,m2 和 m3 是次要的

向m1插入一条记录后,我访问m2,m3,看到m1插入的记录出现在m2,m3上。有效

但是当我尝试使用 NodeJS 连接到 mongodb 时,请使用 mongoose:

mongoose.connect('mongodb://localhost:27018,localhost:27019,localhost:27020/tsng?replicaSet=mongo-rs', {
  autoIndex: false,
  reconnectTries: Number.MAX_VALUE,
  reconnectInterval: 500,
  autoReconnect: true,
  poolSize: 10,
  bufferMaxEntries: 0,
  useNewUrlParser: true,
  useFindAndModify: false,
})

并且抛出了一个错误:

failed to connect to server [m3:27017] on first connect [Error: getaddrinfo ENOTFOUND m3
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:69:26) {
  name: 'MongoNetworkError'
}]

还有一个问题,如果我像上面那样连接到多个 mongodb,我可以选择配置吗,如果 mongodb 之一没有启动或失败,NodeJS 仍然可以在启动的 mongodb 上工作?

【问题讨论】:

    标签: node.js mongodb docker mongoose


    【解决方案1】:

    MongoDB replicaSet member discovery 的工作原理是连接到 mongodb connection string 中列出的成员之一,然后通过 replicaSet 中配置的副本成员主机名(您启动 replicaSet 时使用的主机名)查找。

    来自 MongoDB docs on the matter(在 host[:port] 下):

    对于副本集,指定 mongod 实例的主机名 如副本集配置中所列。

    这意味着您在启动副本集时提供的主机名是您将用来连接到它的主机名。

    我首选的解决方案是创建一个 docker-compose.yml 文件来配置 mongodb 集群和 nodejs 应用程序,从而使其更容易扩展和缩减,及时更改配置,并且它还创建了一个 docker 网络允许您使用容器或服务名称作为 docker 网络中的 DNS 记录。 here's 一个很好的例子,说明如何创建这样的设置。但总的来说,这里有一个快速的 sn-p:

    version: "3"
    services:
      myawesomenodejsapplication:
        container_name: myawesomenodejscontainer
        image: my-awesome-nodejs-application-image
        restart: on-failure
        networks:
          default:
        depends_on:
          - mongo1
          - mongo2
          - mongo3
      mongo1:
        hostname: mongo1
        container_name: localmongo1
        image: mongo
        expose:
        - 27017
        ports:
          - 27017:27017
        restart: always
        entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs0" ]
      mongo2:
        hostname: mongo2
        container_name: localmongo2
        image: mongo
        expose:
        - 27017
        ports:
        - 27018:27017
        restart: always
        entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs0" ]
      mongo3:
        hostname: mongo3
        container_name: localmongo3
        image: mongo
        expose:
        - 27017
        ports:
        - 27019:27017
        restart: always
        entrypoint: [ "/usr/bin/mongod", "--bind_ip_all", "--replSet", "rs0" ]
    

    然后你可以用 docker-compose 初始化集群(就像上面添加的示例链接中指定的那样):

    docker-compose up -d
    docker exec -it localmongo1 mongo
    
    rs.initiate(
      {
        _id : 'rs0',
        members: [
          { _id : 0, host : "mongo1:27017" },
          { _id : 1, host : "mongo2:27017" },
          { _id : 2, host : "mongo3:27017", arbiterOnly: true }
        ]
      }
    )
    
    exit
    

    因为我们将 mongodb1-3 设置为容器主机名,我们可以使用它们连接到集合。

    如果您打算有一天移动集群或更改配置,您需要相应地更改集合成员主机名

    【讨论】:

    • 这意味着我需要更新配置(添加 arbiterOnly: true)并且只需要连接到 set 的一个成员?像上面这样更新我有很多次所以我稍后会更新
    • 不完全是,您需要指定所有成员,以便在重新选举主节点或其中一个成员关闭时,您仍然可以与集群通信,希望它在将来重新建立连接
    • 我该怎么做?我在哪一步做错了什么?根据我的问题,我该如何解决?
    • 如果您想使用现有的副本集,您需要将容器与 docker 网络连接或转储其内容并将它们加载到新的容器中,无需多个即可管理它们只是有点复杂具有不同 IP 地址或某些 VLAN dns 记录的主机,例如在手动或使用撰写文件创建的 docker 网络中
    • 对不起,我没有 docker 方面的经验。能给我发一份教程吗。我创建了 3 db 作为我的问题,使用 robo3T 连接到 3 db 作品,但不能使用 mongoose 连接多个 db
    猜你喜欢
    • 2020-07-14
    • 2013-03-30
    • 2019-11-29
    • 2015-09-26
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    相关资源
    最近更新 更多