mongoError: Topology was destroyed
mongoError: Topology was destroyed
我在 node.js 中内置了一个 REST 服务,其中包含 Restify 和 Mongoose,还有一个 mongoDB 包含一个包含大约 30.000 个常规大小文档的集合。
我有我的节点服务 运行 通过 pmx 和 pm2.
昨天,突然之间,node 开始用消息 "MongoError: Topology was destroyed" 报错,仅此而已。
我不知道这是什么意思,也不知道是什么触发了它。 google-搜索此内容时也没有什么可找到的。所以我想我应该在这里问。
今天重新启动节点服务后,错误不再出现。
我也有其中一个 运行 在生产中,这让我害怕这可能在任何给定时间发生在设置 运行 的一个非常关键的部分......
我正在使用上述软件包的以下版本:
- 猫鼬:4.0.3
- 修改:3.0.3
- 节点:0.10.25
这似乎意味着您的节点服务器与您的 MongoDB 实例的连接在尝试写入时被中断。
看看Mongo source code that generates that error
Mongos.prototype.insert = function(ns, ops, options, callback) {
if(typeof options == 'function') callback = options, options = {};
if(this.s.state == DESTROYED) return callback(new MongoError(f('topology was destroyed')));
// Topology is not connected, save the call in the provided store to be
// Executed at some point when the handler deems it's reconnected
if(!this.isConnected() && this.s.disconnectHandler != null) {
callback = bindToCurrentDomain(callback);
return this.s.disconnectHandler.add('insert', ns, ops, options, callback);
}
executeWriteOperation(this.s, 'insert', ns, ops, options, callback);
}
这似乎与评论中引用的 Sails 问题无关,因为没有安装导致崩溃的升级或 "fix"
我知道 Jason 的回答被接受了,但我对 Mongoose 也有同样的问题,发现 the service hosting my database recommended to apply the following settings 为了在生产中保持 Mongodb 的连接:
var options = {
server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }
};
mongoose.connect(secrets.db, options);
我希望这个回复可以帮助其他有 "Topology was destroyed" 错误的人。
我也有同样的错误。最后,我发现我的代码有一些错误。我为两个 nodejs 服务器使用负载平衡,但我只更新了一个服务器的代码。
我更换了我的mongod服务器from standalone to replication
,但是我忘记对连接字符串做相应的更新,所以我遇到了这个错误。
独立连接字符串:
mongodb://server-1:27017/mydb
复制连接字符串:
mongodb://server-1:27017,server-2:27017,server-3:27017/mydb?replicaSet=myReplSet
此错误是由于 mongo 驱动程序出于任何原因断开连接(例如服务器已关闭)。
默认情况下 mongoose 将尝试重新连接 30 秒,然后停止重试并永远抛出错误,直到重新启动。
您可以通过在连接选项中编辑这两个字段来更改此设置
mongoose.connect(uri,
{ server: {
// sets how many times to try reconnecting
reconnectTries: Number.MAX_VALUE,
// sets the delay between every retry (milliseconds)
reconnectInterval: 1000
}
}
);
只是对 Gaafar 回答的一个小补充,它给了我一个弃用警告。而不是在服务器对象上,像这样:
MongoClient.connect(MONGO_URL, {
server: {
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 1000
}
});
它可以在顶级对象上进行。基本上,只需将其从服务器对象中取出并放入选项对象中,如下所示:
MongoClient.connect(MONGO_URL, {
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 1000
});
我在 MongoDb Compass 社区上创建新数据库时遇到此错误。问题出在我的 Mongod 上,而不是 运行ning。因此,作为修复,我必须 运行 前面的 Mongod 命令。
C:\Program Files\MongoDB\Server.6\bin>mongod
我可以在 运行 执行该命令后创建数据库。
希望对您有所帮助。
我通过以下方式解决了这个问题:
- 确保 mongo 是 运行
- 正在重启我的服务器
根据 this comment,"Topology was destroyed" 可能是由于 mongo 在创建 mongo 文档索引之前断开连接造成的
为了确保所有模型在断开之前都建立了索引,您可以:
await Promise.all(mongoose.modelNames().map(model => mongoose.model(model).ensureIndexes()));
await mongoose.disconnect();
我在kubernetes/minikube + nodejs + mongoose 环境中遇到了这个。
问题是 DNS 服务有一种延迟。检查 DNS 是否准备就绪解决了我的问题。
const dns = require('dns');
var dnsTimer = setInterval(() => {
dns.lookup('mongo-0.mongo', (err, address, family) => {
if (err) {
console.log('DNS LOOKUP ERR', err.code ? err.code : err);
} else {
console.log('DNS LOOKUP: %j family: IPv%s', address, family);
clearTimeout(dnsTimer);
mongoose.connect(mongoURL, db_options);
}
});
}, 3000);
var db = mongoose.connection;
var db_options = {
autoReconnect:true,
poolSize: 20,
socketTimeoutMS: 480000,
keepAlive: 300000,
keepAliveInitialDelay : 300000,
connectTimeoutMS: 30000,
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 1000,
useNewUrlParser: true
};
(db_options 中的数字是在 Whosebug 和类似网站上任意找到的)
在我的例子中,此错误是由 'async'
内的 'await' 部分中的 db.close();
引起的
MongoClient.connect(url, {poolSize: 10, reconnectTries: Number.MAX_VALUE, reconnectInterval: 1000}, function(err, db) {
// Validate the connection to Mongo
assert.equal(null, err);
// Query the SQL table
querySQL()
.then(function (result) {
console.log('Print results SQL');
console.log(result);
if(result.length > 0){
processArray(db, result)
.then(function (result) {
console.log('Res');
console.log(result);
})
.catch(function (err) {
console.log('Err');
console.log(err);
})
} else {
console.log('Nothing to show in MySQL');
}
})
.catch(function (err) {
console.log(err);
});
db.close(); // <--------------------------------THIS LINE
});
就我而言,此错误是由已经 运行 背景的相同服务器实例引起的。
奇怪的是,当我启动我的服务器时没有注意到已经有一个 运行,控制台没有显示 'something is using port xxx' 之类的东西。我什至可以上传一些东西到服务器。所以,我花了很长时间才定位到这个问题。
而且,在关闭所有我能想到的应用程序后,我仍然无法在我的Mac的activity监视器中找到正在使用该端口的进程。我必须使用 lsof
来跟踪。罪魁祸首并不奇怪——它是一个节点进程。但是,通过终端显示的PID,我发现监视器中的端口号与我的服务器使用的端口号不同。
总而言之,杀掉所有node进程可能直接解决这个问题
Sebastian 对 Adrien 回答的评论需要更多关注,它对我有帮助,但它有时可能会被忽略所以这是一个解决方案:
var options = { useMongoClient: true, keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000 }
mongoose.connect(config.mongoConnectionString, options, (err) => {
if(err) {
console.error("Error while connecting", err);
}
});
我为此苦苦挣扎了一段时间 - 正如您从其他答案中看到的那样,问题可能非常不同。
找出原因的最简单方法是在选项
中打开loggerLevel: 'info'
这是我所做的,效果很好。添加以下选项后问题消失了。
const dbUrl = "mongodb://localhost:27017/sampledb";
const options = { useMongoClient: true, keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000, useNewUrlParser: true }
mongoose.connect(dbUrl,options, function(
error
) {
if (error) {
console.log("mongoerror", error);
} else {
console.log("connected");
}
});
您需要重启mongo来解决拓扑错误,然后只需更改mongoose或mongoclient的一些选项即可解决此问题:
var mongoOptions = {
useMongoClient: true,
keepAlive: 1,
connectTimeoutMS: 30000,
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 5000,
useNewUrlParser: true
}
mongoose.connect(mongoDevString,mongoOptions);
这里使用 mongoose,但你可以在没有它的情况下进行类似的检查
export async function clearDatabase() {
if (mongoose.connection.readyState === mongoose.connection.states.disconnected) {
return Promise.resolve()
}
return mongoose.connection.db.dropDatabase()
}
我的用例只是测试抛出错误,所以如果我们断开连接,我不会 运行 操作。
我最近遇到了这个问题。这是我的工作:
- 重启MongoDb:
sudo service mongod restart
- 重启我的NodeJS APP。我使用 pm2 来处理这个
pm2 restart [your-app-id]
。要获取 ID,请使用 pm2 list
我在 node.js 中内置了一个 REST 服务,其中包含 Restify 和 Mongoose,还有一个 mongoDB 包含一个包含大约 30.000 个常规大小文档的集合。 我有我的节点服务 运行 通过 pmx 和 pm2.
昨天,突然之间,node 开始用消息 "MongoError: Topology was destroyed" 报错,仅此而已。 我不知道这是什么意思,也不知道是什么触发了它。 google-搜索此内容时也没有什么可找到的。所以我想我应该在这里问。
今天重新启动节点服务后,错误不再出现。 我也有其中一个 运行 在生产中,这让我害怕这可能在任何给定时间发生在设置 运行 的一个非常关键的部分......
我正在使用上述软件包的以下版本:
- 猫鼬:4.0.3
- 修改:3.0.3
- 节点:0.10.25
这似乎意味着您的节点服务器与您的 MongoDB 实例的连接在尝试写入时被中断。
看看Mongo source code that generates that error
Mongos.prototype.insert = function(ns, ops, options, callback) {
if(typeof options == 'function') callback = options, options = {};
if(this.s.state == DESTROYED) return callback(new MongoError(f('topology was destroyed')));
// Topology is not connected, save the call in the provided store to be
// Executed at some point when the handler deems it's reconnected
if(!this.isConnected() && this.s.disconnectHandler != null) {
callback = bindToCurrentDomain(callback);
return this.s.disconnectHandler.add('insert', ns, ops, options, callback);
}
executeWriteOperation(this.s, 'insert', ns, ops, options, callback);
}
这似乎与评论中引用的 Sails 问题无关,因为没有安装导致崩溃的升级或 "fix"
我知道 Jason 的回答被接受了,但我对 Mongoose 也有同样的问题,发现 the service hosting my database recommended to apply the following settings 为了在生产中保持 Mongodb 的连接:
var options = {
server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }
};
mongoose.connect(secrets.db, options);
我希望这个回复可以帮助其他有 "Topology was destroyed" 错误的人。
我也有同样的错误。最后,我发现我的代码有一些错误。我为两个 nodejs 服务器使用负载平衡,但我只更新了一个服务器的代码。
我更换了我的mongod服务器from standalone to replication
,但是我忘记对连接字符串做相应的更新,所以我遇到了这个错误。
独立连接字符串:
mongodb://server-1:27017/mydb
复制连接字符串:
mongodb://server-1:27017,server-2:27017,server-3:27017/mydb?replicaSet=myReplSet
此错误是由于 mongo 驱动程序出于任何原因断开连接(例如服务器已关闭)。
默认情况下 mongoose 将尝试重新连接 30 秒,然后停止重试并永远抛出错误,直到重新启动。
您可以通过在连接选项中编辑这两个字段来更改此设置
mongoose.connect(uri,
{ server: {
// sets how many times to try reconnecting
reconnectTries: Number.MAX_VALUE,
// sets the delay between every retry (milliseconds)
reconnectInterval: 1000
}
}
);
只是对 Gaafar 回答的一个小补充,它给了我一个弃用警告。而不是在服务器对象上,像这样:
MongoClient.connect(MONGO_URL, {
server: {
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 1000
}
});
它可以在顶级对象上进行。基本上,只需将其从服务器对象中取出并放入选项对象中,如下所示:
MongoClient.connect(MONGO_URL, {
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 1000
});
我在 MongoDb Compass 社区上创建新数据库时遇到此错误。问题出在我的 Mongod 上,而不是 运行ning。因此,作为修复,我必须 运行 前面的 Mongod 命令。
C:\Program Files\MongoDB\Server.6\bin>mongod
我可以在 运行 执行该命令后创建数据库。
希望对您有所帮助。
我通过以下方式解决了这个问题:
- 确保 mongo 是 运行
- 正在重启我的服务器
"Topology was destroyed" 可能是由于 mongo 在创建 mongo 文档索引之前断开连接造成的
为了确保所有模型在断开之前都建立了索引,您可以:
await Promise.all(mongoose.modelNames().map(model => mongoose.model(model).ensureIndexes()));
await mongoose.disconnect();
我在kubernetes/minikube + nodejs + mongoose 环境中遇到了这个。 问题是 DNS 服务有一种延迟。检查 DNS 是否准备就绪解决了我的问题。
const dns = require('dns');
var dnsTimer = setInterval(() => {
dns.lookup('mongo-0.mongo', (err, address, family) => {
if (err) {
console.log('DNS LOOKUP ERR', err.code ? err.code : err);
} else {
console.log('DNS LOOKUP: %j family: IPv%s', address, family);
clearTimeout(dnsTimer);
mongoose.connect(mongoURL, db_options);
}
});
}, 3000);
var db = mongoose.connection;
var db_options = {
autoReconnect:true,
poolSize: 20,
socketTimeoutMS: 480000,
keepAlive: 300000,
keepAliveInitialDelay : 300000,
connectTimeoutMS: 30000,
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 1000,
useNewUrlParser: true
};
(db_options 中的数字是在 Whosebug 和类似网站上任意找到的)
在我的例子中,此错误是由 'async'
内的 'await' 部分中的db.close();
引起的
MongoClient.connect(url, {poolSize: 10, reconnectTries: Number.MAX_VALUE, reconnectInterval: 1000}, function(err, db) {
// Validate the connection to Mongo
assert.equal(null, err);
// Query the SQL table
querySQL()
.then(function (result) {
console.log('Print results SQL');
console.log(result);
if(result.length > 0){
processArray(db, result)
.then(function (result) {
console.log('Res');
console.log(result);
})
.catch(function (err) {
console.log('Err');
console.log(err);
})
} else {
console.log('Nothing to show in MySQL');
}
})
.catch(function (err) {
console.log(err);
});
db.close(); // <--------------------------------THIS LINE
});
就我而言,此错误是由已经 运行 背景的相同服务器实例引起的。
奇怪的是,当我启动我的服务器时没有注意到已经有一个 运行,控制台没有显示 'something is using port xxx' 之类的东西。我什至可以上传一些东西到服务器。所以,我花了很长时间才定位到这个问题。
而且,在关闭所有我能想到的应用程序后,我仍然无法在我的Mac的activity监视器中找到正在使用该端口的进程。我必须使用 lsof
来跟踪。罪魁祸首并不奇怪——它是一个节点进程。但是,通过终端显示的PID,我发现监视器中的端口号与我的服务器使用的端口号不同。
总而言之,杀掉所有node进程可能直接解决这个问题
Sebastian 对 Adrien 回答的评论需要更多关注,它对我有帮助,但它有时可能会被忽略所以这是一个解决方案:
var options = { useMongoClient: true, keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000 }
mongoose.connect(config.mongoConnectionString, options, (err) => {
if(err) {
console.error("Error while connecting", err);
}
});
我为此苦苦挣扎了一段时间 - 正如您从其他答案中看到的那样,问题可能非常不同。
找出原因的最简单方法是在选项
中打开loggerLevel: 'info'
这是我所做的,效果很好。添加以下选项后问题消失了。
const dbUrl = "mongodb://localhost:27017/sampledb";
const options = { useMongoClient: true, keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000, useNewUrlParser: true }
mongoose.connect(dbUrl,options, function(
error
) {
if (error) {
console.log("mongoerror", error);
} else {
console.log("connected");
}
});
您需要重启mongo来解决拓扑错误,然后只需更改mongoose或mongoclient的一些选项即可解决此问题:
var mongoOptions = {
useMongoClient: true,
keepAlive: 1,
connectTimeoutMS: 30000,
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 5000,
useNewUrlParser: true
}
mongoose.connect(mongoDevString,mongoOptions);
这里使用 mongoose,但你可以在没有它的情况下进行类似的检查
export async function clearDatabase() {
if (mongoose.connection.readyState === mongoose.connection.states.disconnected) {
return Promise.resolve()
}
return mongoose.connection.db.dropDatabase()
}
我的用例只是测试抛出错误,所以如果我们断开连接,我不会 运行 操作。
我最近遇到了这个问题。这是我的工作:
- 重启MongoDb:
sudo service mongod restart
- 重启我的NodeJS APP。我使用 pm2 来处理这个
pm2 restart [your-app-id]
。要获取 ID,请使用pm2 list