问题描述
尝试使用 ExpressJS+Mongoose 连接 MongoDB 的时候,发现怎么连接都连接不上,报错如下:
Server is running on port 5000
MongoDB connection error: MongooseServerSelectionError: connect ECONNREFUSED ::1:27017
at _handleConnectionErrors (D:\Projects\server\node_modules\mongoose\lib\connection.js:816:11)
at NativeConnection.openUri (D\Projects\server\node_modules\mongoose\lib\connection.js:791:11)
at runNextTicks (node:internal/process/task_queues:60:5)
at listOnTimeout (node:internal/timers:538:9)
at process.processTimers (node:internal/timers:512:7) {
reason: TopologyDescription {
type: 'Unknown',
servers: Map(1) { 'localhost:27017' => [ServerDescription] },
stale: false,
compatible: true,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
setName: null,
maxElectionId: null,
maxSetVersion: null,
commonWireVersion: 0,
logicalSessionTimeoutMinutes: null
},
code: undefined
}
核心报错是
connect ECONNREFUSED ::1:27017
反复检查过本机的 MongoDB 是成功启动了的,后来在查阅 Mongoose 的官方参数发现还提供了 family 参数:
- 取值为
4:当将family参数设置为4时,意味着强制要求 Mongoose 在连接 MongoDB 服务器时优先使用 IPv4 协议进行连接。这在一些特定场景下很有用,比如你的网络环境中 IPv4 配置更为稳定可靠,或者服务器端对 IPv4 连接做了更优化的设置,通过设置该值,就能确保连接走 IPv4 通道,避免因默认的协议选择机制而可能出现的连接问题(例如默认先尝试 IPv6 但网络中 IPv6 存在访问限制等情况)。 - 取值为
6:若把family参数设成6,则指示 Mongoose 优先采用 IPv6 协议去连接 MongoDB 服务器。在网络全面支持 IPv6 且希望利用 IPv6 相关优势(如更大的地址空间等)的环境中,可以进行这样的设置,不过要确保整个网络链路、服务器等对 IPv6 连接都是畅通且适配的。 - 取值为
auto(默认值) :默认情况下,family参数的值就是auto,此时 Mongoose 会按照先尝试 IPv6 协议进行连接的顺序,如果 IPv6 连接尝试失败或者遇到问题(比如无法找到对应的服务器、超时等情况),它会接着尝试使用 IPv6 协议去连接 MongoDB 服务器,以此来保障最终能够建立起有效的连接。
问题解决
后来在 StackOverflow解决链接上找到了核心问题点:MongoDB默认使用的IPv6协议绑定localhost,所以我们的结局方式有如下几种:
- Windows 本机设置 IPv4 优先级高于 IPv6;(动作太大)
- 连接串设置为 127.0.0.1 =>
mongoose.connect(mongodb://127.0.0.1:27017/xxx, ...; - 连接串使用 family 参数指定 IPv4协议 ↓
mongoose.connect('mongodb://localhost:27017/todo-list', { useNewUrlParser: true, useUnifiedTopology: true, serverSelectionTimeoutMS: 5000, // 设置服务器选择超时时间为5秒,可根据实际情况调整 family: 4 // 指定优先使用IPv4进行连接 }) .then(() => console.log('Connected to MongoDB')) .catch(err => console.error('MongoDB connection error:', err));