Czy mongoDB ma problemy z ponownym połączeniem, czy robię to źle?

Używam nodejs i mongoDB - i mam problemy z połączeniem.

Cóż, właściwie problemy z "pobudką"! Łączy się doskonale - jest super szybki i ogólnie jestem zadowolony z efektów.

Mój problem: Jeśli nie korzystam z połączenia przez jakiś czas (mówię while, bo czas waha się 5+ min), wydaje się, że się przeciąga. Nie dostaję odpalenia zdarzeń rozłączenia - po prostu wisi.

W końcu otrzymuję odpowiedź typu Error: failed to connect to [ * .mongolab.com:*] - (*=wartości maskowane)

Szybki restart aplikacji i połączenie jest świetne ponownie. Czasami, jeśli nie uruchom ponownie aplikacji, mogę odświeżyć i ponownie połączyć się szczęśliwie.

Dlatego myślę, że to kwestia "czuwania".

Przybliżony zarys kodu:

Nie podałem kodu - nie sądzę, żeby był potrzebny. Działa (oprócz przerwania połączenia)

Rzeczy do zapamiętania: jest tylko jeden "connect" - nigdy go nie zamykam. I nigdy nie otwierajcie ponownie.

Używam mangusty, socketio.
/* constants */

var mongoConnect = 'myworkingconnectionstring-includingDBname';


/* includes */

/* settings */

/* Schema */

var db = mongoose.connect(mongoConnect);

    /* Socketio */

io.configure(function (){
    io.set('authorization', function (handshakeData, callback) {

    });
});

io.sockets.on('connection', function (socket) {

});//sockets

io.sockets.on('disconnect', function(socket) {
    console.log('socket disconnection')
});

/* The Routing */

app.post('/login', function(req, res){  

});

app.get('/invited', function(req, res){

});

app.get('/', function(req, res){

});

app.get('/logout', function(req, res){

});

app.get('/error', function(req, res){

});

server.listen(port);
console.log('Listening on port '+port);

db.connection.on('error', function(err) {
    console.log("DB connection Error: "+err);
});
db.connection.on('open', function() {
    console.log("DB connected");
});
db.connection.on('close', function(str) {
    console.log("DB disconnected: "+str);
});

Próbowałem różnych configów tutaj, jak otwieranie i zamykanie przez cały czas - wierzę jednak, że ogólny konsensus jest zrobić tak, jak ja jestem z jednym otwartym opakowaniem. ??

Próbowałem testera połączenia, który sprawdza status połączenia... chociaż wydaje się, że wszystko jest w porządku-problem nadal się dzieje.

Mam ten problem od pierwszego dnia. Zawsze gościłem MongoDB z MongoLab. Problem wydaje się być gorszy na localhost. Ale nadal mam problem na Azure i teraz nodejit.su.

Jak to się dzieje wszędzie-to musi być ja, MongoDB, albo mongolab.

Nawiasem mówiąc miałem podobne doświadczenie ze sterownikiem php. (aby potwierdzić to na nodejs chociaż)

Byłoby świetnie dla jakiejś pomocy - nawet jeśli ktoś po prostu powie "to jest normalne"

Z góry dzięki

Rob

Author: jared, 2012-12-21

6 answers

Aktualizacja: nasz artykuł pomocy technicznej dla tego tematu (zasadniczo kopia tego postu) został przeniesiony do nasz dokument rozwiązywania problemów z połączeniem.

[4]} znany jest problem polegający na tym, że sieć Azure IaaS wymusza limit czasu bezczynności wynoszący około trzynaście minut (osiągnięty empirycznie). Pracujemy z platformą Azure, aby sprawdzić, czy nie możemy uczynić rzeczy bardziej przyjaznymi dla użytkownika, ale w międzyczasie inne odniosły sukces, konfigurując opcje sterowników, aby obejść problem.

Max czas bezczynności połączenia

Najskuteczniejszym obejściem, jakie znaleźliśmy podczas pracy z platformą Azure i naszymi klientami, było ustawienie maksymalnego czasu bezczynności połączenia poniżej czterech minut. Chodzi o to, aby sterownik przetwarzał bezczynne połączenia, zanim zapora wymusi problem. Na przykład, jeden klient, który używa sterownika C#, ustawił MongoDefaults.MaxConnectionIdleTime na jedną minutę i rozwiązał ich problemy.

MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);

Sam kod aplikacji się nie zmienił, ale teraz za kulisami sterownik agresywnie przetwarza bezczynne połączenia. Wynik można również zobaczyć w dziennikach serwera: wiele przerw połączenia podczas okresów bezczynności w aplikacji.

Aby uzyskać więcej informacji na temat tego podejścia, zapoznaj się z pokrewnym wątkiem użytkownika mongo, SocketException using C# driver on azure.

Keepalive

Możesz również obejść problem, czyniąc swoje połączenia mniej bezczynnymi za pomocą pewnego rodzaju keepalive . Jest to trochę trudne do wdrożenia, chyba że kierowca obsługuje go po wyjęciu z pudełka, Zwykle korzystając z TCP Keepalive . Jeśli chcesz rzucić własne, upewnij się, że chwytasz każde bezczynne połączenie z puli co kilka minut i wydajesz proste i tanie polecenie, prawdopodobnie ping .

Obsługa rozłączników

Rozłączenia mogą się zdarzyć od czasu do czasu, nawet bez agresywnej konfiguracji zapory. Zanim wejdziesz do produkcji, chcesz mieć pewność, że prawidłowo je obsługujesz.

Po pierwsze, upewnij się aby włączyć automatyczne ponowne połączenie. Sposób, w jaki to zrobić, różni się w zależności od Sterownika, ale gdy sterownik wykryje, że operacja nie powiodła się, ponieważ połączenie było złe włączenie auto reconnect informuje Sterownika o próbie ponownego połączenia.

Ale to nie do końca rozwiązuje problem. Nadal masz problem z tym, co zrobić z nieudaną operacją, która wywołała ponowne połączenie. Automatyczne ponowne połączenie nie powoduje automatycznego ponowienia nieudanych operacji. To byłoby niebezpieczne, zwłaszcza dla pisarek. Więc zwykle wyjątek jest wyrzucany, a aplikacja jest proszona o obsługę go. Często powtarzanie lektur jest bezmyślne. Ale ponowne próby pisania powinny być starannie przemyślane.

Sesja powłoki mongo poniżej pokazuje problem. Powłoka mongo domyślnie ma włączone automatyczne ponowne połączenie. Wstawiam dokument do kolekcji o nazwie stuff, a następnie znajduję wszystkie dokumenty w tej kolekcji. Następnie ustawiłem timer na trzydzieści minut i spróbowałem ponownie tego samego znaleziska. Nie powiodło się, ale powłoka automatycznie ponownie się połączyła i kiedy natychmiast ponownie moje znalezisko działało zgodnie z oczekiwaniami.

% mongo ds012345.mongolab.com:12345/mydatabase -u *** -p *** 
MongoDB shell version: 2.2.2 
connecting to: ds012345.mongolab.com:12345/mydatabase 
> db.stuff.insert({}) 
> db.stuff.find() 
{ "_id" : ObjectId("50f9b77c27b2e67041fd2245") } 
> db.stuff.find() 
Fri Jan 18 13:29:28 Socket recv() errno:60 Operation timed out 192.168.1.111:12345 
Fri Jan 18 13:29:28 SocketException: remote: 192.168.1.111:12345 error: 9001 socket exception [1] server [192.168.1.111:12345] 
Fri Jan 18 13:29:28 DBClientCursor::init call() failed 
Fri Jan 18 13:29:28 query failed : mydatabase.stuff {} to: ds012345.mongolab.com:12345 
Error: error doing query: failed 
Fri Jan 18 13:29:28 trying reconnect to ds012345.mongolab.com:12345 
Fri Jan 18 13:29:28 reconnect ds012345.mongolab.com:12345 ok 
> db.stuff.find() 
{ "_id" : ObjectId("50f9b77c27b2e67041fd2245") }

Jesteśmy tu, aby pomóc

Oczywiście, jeśli masz jakieś pytania, skontaktuj się z nami pod adresem [email protected] jesteśmy tu, by pomóc.

 27
Author: jared,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-04 21:08:38

Dzięki za pomoc-udało mi się rozwiązać ten problem zarówno na localhost, jak i wdrożony na serwerze na żywo.

Oto mój działający kod połączenia:

var MONGO = {
    username: "username",
    password: "pa55W0rd!",
    server: '******.mongolab.com',
    port: '*****',
    db: 'dbname',
    connectionString: function(){
        return 'mongodb://'+this.username+':'+this.password+'@'+this.server+':'+this.port+'/'+this.db;
    },
    options: {
        server:{
            auto_reconnect: true,
            socketOptions:{
                connectTimeoutMS:3600000,
                keepAlive:3600000,
                socketTimeoutMS:3600000
            }
        }
    }
};

var db = mongoose.createConnection(MONGO.connectionString(), MONGO.options);

db.on('error', function(err) {
    console.log("DB connection Error: "+err);
});
db.on('open', function() {
    console.log("DB connected");
});
db.on('close', function(str) {
    console.log("DB disconnected: "+str);
});

Myślę, że największą zmianą było użycie "createConnection" zamiast "connect" - używałem tego wcześniej, ale może opcje pomagają teraz. Ten artykuł bardzo pomógł http://journal.michaelahlers.org/2012/12/building-with-nodejs-persistence.html

Jeśli mam być szczery, nie jestem zbyt pewien, dlaczego dodałem te opcje-jak wspomniano przez @ jareed, znalazłem również kilka osób mających sukces z "MaxConnectionIdleTime" - ale o ile widzę sterownik javascript nie ma tej opcji: to była moja próba próby replikacji zachowania.

Jak na razie tak dobrze-mam nadzieję, że to komuś pomoże.

Aktualizacja: 18 kwietnia 2013 uwaga, jest to druga aplikacja z inną konfiguracją

Teraz myślałem, że mam to rozwiązane, ale problem wzrósł to brzydka Głowa znowu na kolejna aplikacja ostatnio-z tym samym kodem połączenia. Zdezorientowany!!!

Jednak ustawienie było nieco inne ...

Ta nowa aplikacja była uruchomiona na polu windows przy użyciu IISNode. początkowo nie postrzegałem tego jako ważnego.

Czytałem, że prawdopodobnie były jakieś problemy z mongo na Azure (@jareed), więc przeniosłem DB do AWS - nadal problem utrzymywał się.

Więc zacząłem grać o tym options object ponownie, czytając sporo na nim. Came do tego wniosku:

options: {
    server:{
        auto_reconnect: true,
        poolSize: 10,
        socketOptions:{
            keepAlive: 1
        }
    },
    db: {
        numberOfRetries: 10,
        retryMiliSeconds: 1000
    }
}
To było trochę bardziej wykształcone niż moje pierwotne opcje. Jednak-to nadal nie jest dobre.

Teraz, z jakiegoś powodu musiałem wysiąść z tego okna windows (coś związanego z modułem, który nie kompiluje się na nim) - łatwiej było się przenieść, niż spędzić kolejny tydzień próbując go uruchomić.

Więc przeniosłem swoją aplikację do nodejitsu. nisko i oto mój związek pozostał przy życiu! Woo!

Więc ... nie mam pojęcia! Co robię wiem, że te opcje wydają się działać na Nodejitsu.... dla mnie.

Wierzę, że IISNode używa jakiegoś skryptu "na zawsze", aby utrzymać aplikację przy życiu. Teraz, aby być sprawiedliwym aplikacja nie zawiesza się, aby to kopać, ale myślę, że musi być jakiś "cykl aplikacji", który jest stale odświeżany - w ten sposób może to zrobić ciągłe wdrażanie (kod ftp, nie ma potrzeby ponownego uruchamiania aplikacji) - może to jest czynnik; ale po prostu zgaduję teraz.

Oczywiście wszystko to oznacza, że to nie jest rozwiązane. On wciąż nierozwiązane. To dla mnie rozwiązane w moim ustawieniu.
 18
Author: rob_james,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-17 12:00:52

Kilka zaleceń dla osób, które nadal mają ten problem:

  1. Upewnij się, że używasz najnowszego klienta mongodb dla węzła.js. Zauważyłem znaczną poprawę w tym obszarze podczas migracji z v1.2.x do v1.3.10 (najnowsze od Dziś)

  2. Możesz przekazać obiekt options do MongoClient.połącz się. Następujące opcje działały dla mnie podczas łączenia się z platformy Azure do MongoLab:

    Options = { db: {}, serwer: { auto_reconnect: true, socketOptions: {keepAlive: 1} }, replSet: {}, mongos: {} };

    MongoClient.connect( dbUrl, options, function( err, dbConn) { // Twój kod });

  3. Zobacz tę inną odpowiedź, w której opisuję, jak obsługiwać zdarzenie "close", które wydaje się być bardziej wiarygodne. https://stackoverflow.com/a/20690008/446681

 6
Author: Hector Correa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:19:26

Włącz auto_reconnect Server opcja taka:

var db = mongoose.connect(mongoConnect, {server: {auto_reconnect: true}});

Połączenie, które tutaj otwierasz, jest w rzeczywistości pulą 5 połączeń (domyślnie), więc masz prawo po prostu połączyć się i pozostawić otwarte. Zgaduję, że czasami tracisz łączność z mongolabem, a twoje połączenia umierają, gdy to nastąpi. Miejmy nadzieję, że włączenie auto_reconnect to rozwiąże.

 1
Author: JohnnyHK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-22 03:21:27

Zwiększenie czasu może pomóc.

  • "socketTimeoutMS" : jak długo może trwać wysyłanie lub odbieranie na gnieździe przed czasem.
  • "wTimeoutMS": kontroluje ile milisekund serwer czeka troska o pisanie, aby być zaspokojonym.
  • "connectTimeoutMS" : ile czasu może zająć otwarcie połączenia przed upływem czasu w milisekundach.

    $m = new MongoClient ("mongodb://127.0.0.1:27017", array ("connect" = > TRUE, "connectTimeoutMS" = > 10, "socketTimeoutMS"= > 10, "wTimeoutMS"=>10));

        $db= $m->mydb;
        $coll = $db->testData;
        $coll->insert($paramArr);
    
 1
Author: djebel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-18 10:53:24

Miałem podobny problem z odłączeniem się od MongoDB . Zrobienie dwóch rzeczy naprawiło to:

  1. Upewnij się, że Twój komputer nigdy nie śpi (co spowoduje utratę połączenia sieciowego).
  2. Omiń router / firewall (lub skonfiguruj go poprawnie, czego jeszcze nie wiem, jak to zrobić).
 0
Author: Mike M. Lin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:06:52