【发布时间】:2023-02-17 17:46:01
【问题描述】:
我正在尝试在 Docker 上设置单节点 MongoDB 复制集并在我的节点应用程序中连接到它,但连接被拒绝。如果我将 mongo 用作独立实例并且没有复制集,则连接工作正常。
这就是我在节点应用程序上连接到 mongo 的方式:
mongoose.connect("mongodb://admin:secretpass@app_mongodb:27017/dbname?authSource=admin&replicaSet=rs0")
这是我收到的错误:
/var/www/worker/node_modules/mongoose/lib/connection.js:824
const serverSelectionError = new ServerSelectionError();
^
MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
Mongo 日志显示该应用程序尝试连接:
{"t":{"$date":"2023-01-27T10:22:46.410+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"172.18.0.10:41318","uuid":"2e1ccbc5-3162-4f64-80f3-8be580079ef6","connectionId":68,"connectionCount":11}}
{"t":{"$date":"2023-01-27T10:22:46.417+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn68","msg":"client metadata","attr":{"remote":"172.18.0.10:41318","client":"conn68","doc":{"driver":{"name":"nodejs|Mongoose","version":"4.11.0"},"os":{"type":"Linux","name":"linux","architecture":"x64","version":"5.10.0-12-amd64"},"platform":"Node.js v19.5.0, LE (unified)","version":"4.11.0|6.7.5"}}}
{"t":{"$date":"2023-01-27T10:22:46.425+00:00"},"s":"I", "c":"NETWORK", "id":22944, "ctx":"conn68","msg":"Connection ended","attr":{"remote":"172.18.0.10:41318","uuid":"2e1ccbc5-3162-4f64-80f3-8be580079ef6","connectionId":68,"connectionCount":10}}
docker-compose.yml :
version: '3.8'
services:
mongodb:
container_name: app_mongodb
build:
dockerfile: ./Dockerfile
x-bake:
no-cache: true
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=secretpass
volumes:
- ./db:/data/db
networks:
- proxy
restart: unless-stopped
worker:
container_name: app_worker
image: "node:latest"
command: "npm run dev"
user: "node"
working_dir: /var/www/worker
environment:
WAIT_HOSTS: app_mongodb:27017
volumes:
- ./worker:/var/www/worker
networks:
- proxy
links:
- mongodb
depends_on:
- mongodb
restart: unless-stopped
networks:
proxy:
external: true
文件:
FROM mongo
# Initiate replica set
RUN echo "secretpasswordkey" > "/tmp/replica.key"
RUN chmod 600 /tmp/replica.key
RUN chown 999:999 /tmp/replica.key
CMD ["mongod", "--replSet", "rs0", "--bind_ip_all", "--keyFile", "/tmp/replica.key"]
我还在启动容器后用 mongosh 运行这个命令(顺便说一句,有没有办法将它添加到 Dockerfile 中?):
rs.initiate({_id: 'rs0', members: [{_id:1, 'host':'127.0.0.1:27017'}]})
快速检查显示副本集确实已初始化:
rs0 [direct: primary] admin> rs.status()
{
set: 'rs0',
date: ISODate("2023-01-27T10:35:44.062Z"),
myState: 1,
term: Long("1"),
syncSourceHost: '',
syncSourceId: -1,
heartbeatIntervalMillis: Long("2000"),
majorityVoteCount: 1,
writeMajorityCount: 1,
votingMembersCount: 1,
writableVotingMembersCount: 1,
optimes: {
lastCommittedOpTime: { ts: Timestamp({ t: 1674815739, i: 1 }), t: Long("1") },
lastCommittedWallTime: ISODate("2023-01-27T10:35:39.161Z"),
readConcernMajorityOpTime: { ts: Timestamp({ t: 1674815739, i: 1 }), t: Long("1") },
appliedOpTime: { ts: Timestamp({ t: 1674815739, i: 1 }), t: Long("1") },
durableOpTime: { ts: Timestamp({ t: 1674815739, i: 1 }), t: Long("1") },
lastAppliedWallTime: ISODate("2023-01-27T10:35:39.161Z"),
lastDurableWallTime: ISODate("2023-01-27T10:35:39.161Z")
},
lastStableRecoveryTimestamp: Timestamp({ t: 1674815679, i: 1 }),
electionCandidateMetrics: {
lastElectionReason: 'electionTimeout',
lastElectionDate: ISODate("2023-01-27T10:25:49.015Z"),
electionTerm: Long("1"),
lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 1674815148, i: 1 }), t: Long("-1") },
lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1674815148, i: 1 }), t: Long("-1") },
numVotesNeeded: 1,
priorityAtElection: 1,
electionTimeoutMillis: Long("10000"),
newTermStartDate: ISODate("2023-01-27T10:25:49.082Z"),
wMajorityWriteAvailabilityDate: ISODate("2023-01-27T10:25:49.111Z")
},
members: [
{
_id: 1,
name: '127.0.0.1:27017',
health: 1,
state: 1,
stateStr: 'PRIMARY',
uptime: 643,
optime: { ts: Timestamp({ t: 1674815739, i: 1 }), t: Long("1") },
optimeDate: ISODate("2023-01-27T10:35:39.000Z"),
lastAppliedWallTime: ISODate("2023-01-27T10:35:39.161Z"),
lastDurableWallTime: ISODate("2023-01-27T10:35:39.161Z"),
syncSourceHost: '',
syncSourceId: -1,
infoMessage: '',
electionTime: Timestamp({ t: 1674815149, i: 1 }),
electionDate: ISODate("2023-01-27T10:25:49.000Z"),
configVersion: 1,
configTerm: 1,
self: true,
lastHeartbeatMessage: ''
}
],
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1674815739, i: 1 }),
signature: {
hash: Binary(Buffer.from("a211cfe3faa237bf8a30ccbc8ca929eea704f467", "hex"), 0),
keyId: Long("7193276291800367109")
}
},
operationTime: Timestamp({ t: 1674815739, i: 1 })
}
关于我做错了什么的想法?谢谢 !
【问题讨论】:
-
你确定吗?连接字符串
mongodb://admin:secretpass@app_mongodb:27017与错误消息connect ECONNREFUSED 127.0.0.1:27017不匹配 尝试使用localhost而不是127.0.0.1 -
创建一个的原因是什么单一成员MongoDB 副本集?
-
请修剪您的代码,以便更容易找到您的问题。按照这些指南创建一个minimal reproducible example。
-
@WernfriedDomscheit 感谢您的评论!它帮助了很多。起初我没有意识到
initiate()指令中的连接url将在客户端连接期间使用。另外为了回答您的问题,我需要在我的应用程序中使用 Change Streams,并且该功能在独立模式下不可用。由于我只有一台服务器可供使用,并且在我的情况下性能比可用性更重要,所以我认为只需要一个实例。
标签: node.js mongodb docker-compose replicaset