mongo Hata: Topoloji yok edildi


163

Restify ve Mongoose ile node.js'de yerleşik bir REST hizmetim ve yaklaşık 30.000 normal boyutlu belgeye sahip bir koleksiyonla bir mongoDB var. Ben düğüm hizmet pmx ve pm2 üzerinden çalışan var.

Dün, aniden, düğüm "MongoError: Topology imha edildi" mesajıyla hatalar çıkarmaya başladı, başka bir şey yok. Bunun ne anlama geldiğini ve bunu neyin tetikleyebileceğini bilmiyorum. Google'da arama yaparken bulunacak çok fazla şey yoktur. Bu yüzden buraya soracağımı düşündüm.

Düğüm hizmetini bugün yeniden başlattıktan sonra hatalar gelmeyi durdurdu. Üretimde çalışan bunlardan biri de var ve bunun herhangi bir zamanda oradaki kurulumun oldukça önemli bir parçasına olabileceğini korkutuyor ...

Belirtilen paketlerin aşağıdaki sürümlerini kullanıyorum:

  • firavun faresi: 4.0.3
  • yeniden boyutlandır: 3.0.3
  • düğüm: 0.10.25

2
Sadece mongodb sürücüsünü kullanırken benzer sorunlar yaşıyorum :(
0x8890

1
Yelken kullanmıyorum, bu yüzden hayır, bunun sorunumu çözeceğini düşünmüyorum
dreagan

Yanıtlar:


98

Bu, düğüm sunucunuzun MongoDB örneğinizle bağlantısının, yazmaya çalışırken kesildiği anlamına geliyor.

Bir göz atın o hatayı oluşturur Mongo kaynak kodu

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);
}

Bu, kilitlenme veya "düzeltme" yi hızlandırmak için herhangi bir yükseltme yüklenmediği için yorumlarda belirtilen Yelkenler sorunu ile ilgili görünmüyor.


2
Ben aynı sorunu var ve neredeyse her hafta olur ve mongo ile çalışan uygulamayı kapatır, bu benim oluşturduğum bir sorun mu yoksa bu mongoose bir sorun mu?
Mohammad Ganji

@MohammadGanji: İstemci kodunda hata ayıklama yaparken ve deyimlerin üstesinden gelmede yeterince hızlı değilken bu hatayı Mongoose olmadan alıyorum. Buna neyin sebep olduğundan emin değilim, ancak moğol sorgularından hemen sonra kesme noktaları ayarlamak bunu önler.
Dan Dascalescu

@DanDascalescu Sorunumun çözüldüğünü, günlüğe kaydetmeyle ilgili bir sorun olduğunu belirtmeyi unuttum, günlüklerde bir gigabayt depolama ve mongo sürecini kapattıktan sonra bazı uyarıları olduğu gibi görünüyor, bu yüzden sıkıştırmayı ve yedeklemeyi denedim ve problem çözüldü
Mohammad Ganji

83

Jason'ın cevabının kabul edildiğini biliyorum, ancak Mongoose ile aynı sorunu yaşadım ve veritabanımı barındıran hizmetin, Mongodb'un bağlantısını üretimde canlı tutmak için aşağıdaki ayarları uygulamasını önerdiğini buldum:

var options = {
  server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
  replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }
};
mongoose.connect(secrets.db, options);

Umarım bu cevap "Topoloji yok edildi" hatalarına sahip diğer insanlara yardımcı olabilir.


4
Bu benim için sorunu çözmedi. Aslında keepAlive'imi 30000'e çıkardım, bu da çok yardımcı oldu. Hala arada sırada topoloji hatası alıp alsam da.
ifightcrime

9
sürümünden 3.4.2 den Mongo sürücüsünü kullanarak, bu seçenekler en üst düzeyde olması gerekir: seçenekleri: {keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000}
Sebastien H.

Istemci kodu hata ayıklama ve ifadeler üzerinde adım yeterince hızlı değilken, Mongoose olmadan bu hatayı alıyorum. Buna neyin sebep olduğundan emin değilim, ancak moğol sorgularından hemen sonra kesme noktaları ayarlamak bunu önler.
Dan Dascalescu

76

Bu hata, mongo sürücüsünün herhangi bir nedenden dolayı bağlantıyı kesmesinden kaynaklanır (örneğin sunucu çalışmıyor).

Varsayılan olarak mongoose 30 saniye boyunca yeniden bağlanmaya çalışır, ardından yeniden denemeyi durdurur ve yeniden başlatılıncaya kadar hataları sonsuza kadar atar.

Bağlantı seçeneklerindeki bu 2 alanı düzenleyerek bunu değiştirebilirsiniz

mongoose.connect(uri, 
    { server: { 
        // sets how many times to try reconnecting
        reconnectTries: Number.MAX_VALUE,
        // sets the delay between every retry (milliseconds)
        reconnectInterval: 1000 
        } 
    }
);

bağlantı seçenekleri belgeleri


3
Evet. Teknik olarak kabul edilen cevap, sorulan soruya cevap verir, ancak bu tartışılan senaryodan kaçınmanın doğru yoludur.
kingdango

3
3.4.2 sürümünden Mongo sürücüsünü kullanan bu seçeneklerin en üst düzeyde olması gerekir: seçenekler: {keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 2000}
Sebastien H.

1
Netleştirmek için, Düğüm MongoDB Sürücüsünün belgelerine göre , sunucu varsayılan olarak her yeniden deneme arasında bir saniye arayla 30 kez yeniden bağlanmaya çalışır.
Boaz

4
Bu seçenekleri şimdi sunucu nesnesi altında sağlamanız gerekmez. Doğrudan seçenek nesnelerine gider.
Animesh Singh

3
Moğolistan'ın son sürümlerinin en üst düzeyde bu seçeneklere sahip olduğunu eklemek istedim, bu yüzden server: {vb.
Alex K

17

Benim durumumda, bu hata db.close();'async' içindeki bir 'bekliyor' bölümünden kaynaklandı

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
});

2
Carlos'un davasında sanırım yakın olan her şeyden önce oldu. Benim durumum benzerdi: DB'yi kapattıktan sonra eriştim. Mongo geliştiricilerinin daha açık hata mesajları üretebilmesi güzel olurdu. "Kırılan Topoloji" dahili bir nota benziyor.
Juan Lanus

3
sizin çözümünüz db.closebir thenbloğa taşınmaktı , değil mi?
AlexChaffee

Doğru, benim durumumda sadece db.close () satırını silmek, ama sonra blok içine taşımak güzel bir çözüm gibi görünüyor.
Carlos Rodríguez

1
db.closeBir thenbloğa taşınmak, yerli MongoDB Node.js sürücüsüyle benim için harika çalıştı.
kevinmicke

12

Gaafar'ın cevabına sadece küçük bir katkı, bana bir amortisman uyarısı verdi. Sunucu nesnesi yerine, şöyle:

MongoClient.connect(MONGO_URL, {
    server: {
        reconnectTries: Number.MAX_VALUE,
        reconnectInterval: 1000
    }
});

Üst düzey nesneye gidebilir. Temel olarak, onu sunucu nesnesinden çıkarın ve şöyle seçenekler nesnesine koyun:

MongoClient.connect(MONGO_URL, {
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 1000
});

7

"Topoloji yok edildi", mongo belgesi dizinleri oluşturulmadan önce tekdüze bağlantısının kesilmesinden kaynaklanıyor olabilir. bu yoruma göre

Bağlantıyı kesmeden önce tüm modellerin dizinlerinin oluşturulduğundan emin olmak için şunları yapabilirsiniz:

await Promise.all(mongoose.modelNames().map(model => mongoose.model(model).ensureIndexes()));

await mongoose.disconnect();

teşekkür ederim, eğer test
senaryoları

1
Bu benim içindi. Teşekkür ederim! Jest'te mongodb-memory-server ile testler yapıyordum, topoloji veya açık tutamaklar / bitmemiş Promises konusunda sporadik hatalar alıyordum. Ama bazen işe yaradı. Dizinlere bekleme eklemek sorunu çözdü.
roblingle

@Roblingle gibi Jest kodu hata ayıklama ve ifadeler üzerinde adım yeterince hızlı olmasa da, Mongoose olmadan bu hatayı alıyorum. Buna neyin sebep olduğundan emin değilim, ancak moğol sorgularından hemen sonra kesme noktaları ayarlamak bunu önler.
Dan Dascalescu

@roblingle nasıl düzelttiniz? Sadece bu problemle karşılaştım ve MongoDB'ye tekrar bağlanmam imkansızdı. O zamandan beri her şeyi sildim ve MongoDB'yi (homebrew aracılığıyla) yeniden kurdum ve şimdi başlangıçta çalışmayacak. (İlgisiz bir konu olabilir)
bobbyz

İlgisiz geliyor. Uygulamam iyi çalıştı ancak testler başarısız oldu.
33 roblingle

3

Sebastian'ın Adrien'ın cevabı hakkındaki yorumu bana yardımcı oldu, ancak bir yorum yapmak bazen görmezden gelebilir, bu yüzden bir çözüm :

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);
    }
});

2

Ben de aynı hatayı aldım. Son olarak, kodumda bazı hatalar buldum. İki nodejs sunucusu için yük dengesini kullanıyorum, ancak sadece bir sunucunun kodunu güncelliyorum.

Mongod sunucumu değiştiriyorum from standalone to replication, ancak bağlantı dizesi için ilgili güncellemeyi yapmayı unutuyorum, bu yüzden bu hatayla karşılaştım.

bağımsız bağlantı dizesi: mongodb://server-1:27017/mydb çoğaltma bağlantı dizesi: mongodb://server-1:27017,server-2:27017,server-3:27017/mydb?replicaSet=myReplSet

ayrıntılar burada :[bağlantı dizesi için mongo doc]


2

Bunu kubernetes / minikube + nodejs + mongoose ortamında tanıştım. Sorun, DNS hizmetinin bir tür gecikme ile dolmasıydı. DNS'yi kontrol etmeye hazırım sorunumu çözdü.

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 içindeki sayılar stackoverflow ve benzeri sitelerde rastgele bulunur)


2

İşte ne yaptım, iyi çalışıyor. Aşağıdaki seçenekler eklendikten sonra sorun giderildi.

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");
  }

});

2

Topoloji hatasını çözmek için mongo'yu yeniden başlatmanız, ardından bu sorunun üstesinden gelmek için mongoose veya mongoclient'ın bazı seçeneklerini değiştirmeniz yeterlidir:

var mongoOptions = {
    useMongoClient: true,
    keepAlive: 1,
    connectTimeoutMS: 30000,
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 5000,
    useNewUrlParser: true
}

mongoose.connect(mongoDevString,mongoOptions);

SO hoş geldiniz! Lütfen yanıtınızı düzenleyin ve daha fazla bilgi ekleyin, örneğin sorunu nasıl çözdüğü hakkında daha fazla bilgi için bkz. Stackoverflow.com/help/how-to-ask
B - rian

1

MongoDb Compass Topluluğumda yeni bir veritabanı oluştururken bu hatayı aldım. Sorun Mongod'umla ilgiliydi, çalışmıyordu. Bir düzeltme olarak, Mongod komutunu önceki gibi çalıştırmam gerekiyordu.

C:\Program Files\MongoDB\Server\3.6\bin>mongod

Bu komutu çalıştırdıktan sonra bir veritabanı oluşturabildim.

Umarım yardımcı olur.


1

Bir süredir bununla uğraşıyordum - Diğer cevaplardan da görebileceğiniz gibi, sorun çok farklı olabilir.

Neyin neden olduğunu bulmanın en kolay yolu, bu loggerLevel: 'info'seçeneklerde açmaktır


0

Benim durumumda, bu hata zaten arka planda çalışan özdeş bir sunucu örneğinden kaynaklandı.

Garip olan şey, önceden çalışan bir tane olduğunu bilmeden sunucuma başladığımda, konsolun 'bir şey port xxx kullanıyor' gibi bir şey göstermediğidir. Sunucuya bir şey bile yükleyebilirim. Bu sorunu bulmak oldukça uzun sürdü.

Dahası, hayal edebildiğim tüm uygulamaları kapattıktan sonra, Mac'in aktivite monitöründe bu bağlantı noktasını kullanan işlemi hala bulamadım. lsofİzlemek için kullanmalıyım . Suçlu şaşırtıcı değildi - bu bir düğüm süreci. Ancak, terminalde gösterilen PID ile, monitördeki bağlantı noktası numarasının sunucum tarafından kullanılandan farklı olduğunu buldum.

Sonuçta, tüm düğüm süreçlerini öldürmek bu sorunu doğrudan çözebilir.


-3

Bu sorunu şu şekilde çözdüm:

  1. mongo'nun çalışmasını sağlamak
  2. sunucumu yeniden başlatma

4
Bu, sorunun tekrar olmasını engellemez
Sam Munroe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.