2013-03-15 6 views
6

Ich habe ein Bash-Shell-Skript, das eine Menge Zeug vor dem Versuch, mongorestore.Wie überprüft man, ob mongodb bereit ist, Verbindungen vom Bash-Skript zu akzeptieren?

Ich möchte sicherstellen, dass nicht nur mongodb ist, aber es ist auch bereit, Verbindungen zu akzeptieren, bevor ich versuche, wiederherzustellen.

gerade jetzt, was ich sehe ist, Mongo-Prozess ist up, aber es dauert 45+ Sekunden, um die Ersteinrichtung (Einrichten von Journal-Dateien usw.), bevor es bereit ist, Verbindungen zu akzeptieren. Idealerweise möchte ich die Verbindung in einer Schleife testen und erst wenn ich eine Verbindung herstellen kann, möchte ich mongorestore ausführen.

Kann jemand mir zeigen, wie man das in bash macht oder mich in die richtige Richtung weist?

Vielen Dank!

--su

+0

Wenn eine mongod-Instanz bereit ist, meldet sich etwas wie "Warten auf Verbindungen auf Port 27017". Sie können das Protokoll einfach abwarten, indem Sie auf diese Ausgabezeile warten, und dann die mongo restore starten, sobald diese Nachricht protokolliert wurde. Nicht sicher, ob dies die beste Lösung ist, aber es sollte funktionieren – ACE

Antwort

7

ich das gleiche Problem vor kurzem hatte. Ich beschloss, mongod zu konfigurieren, um alle seine Ausgabe in eine Protokolldatei zu protokollieren und dann in einer Schleife zu warten, die die Protokolldatei überprüft, bis wir eine Ausgabe sehen, die suggeriert, dass mongod bereit ist.

Dies ist ein Beispiel Logfile Ausgangsleitung wir warten müssen:

Tue Dec 3 14:25:28.217 [initandlisten] waiting for connections on port 27017 

Dies ist die Bash-Skript, das ich kam mit: es warten

 
#!/bin/bash 

# Initialize a mongo data folder and logfile 
mkdir -p /data/db 
touch /var/log/mongodb.log 

# Start mongodb with logging 
# --logpath Without this mongod will output all log information to the standard output. 
# --logappend Ensure mongod appends new entries to the end of the logfile. We create it first so that the below tail always finds something 
/usr/bin/mongod --quiet --logpath /var/log/mongodb.log --logappend & 

# Wait until mongo logs that it's ready (or timeout after 60s) 
COUNTER=0 
grep -q 'waiting for connections on port' /var/log/mongodb.log 
while [[ $? -ne 0 && $COUNTER -lt 60 ]] ; do 
    sleep 2 
    let COUNTER+=2 
    echo "Waiting for mongo to initialize... ($COUNTER seconds so far)" 
    grep -q 'waiting for connections on port' /var/log/mongodb.log 
done 

# Now we know mongo is ready and can continue with other commands 
... 

Hinweis das Skript nicht für immer, Timeout nach 60s - Sie können oder wollen das nicht, je nach Anwendungsfall.

+3

Aber Sie müssen die Mongo-Protokolle zurücksetzen, damit es funktioniert. –

14

Um die Verbindung in einer Schleife zu testen, wie Sie vorschlagen,

until nc -z localhost 27017 
do 
    sleep 1 
done 
+0

tog ... Ich habe Ihren Vorschlag versucht, aber das funktioniert nicht. irgendwelche anderen Ideen? –

+6

Schlechtes Feedback: "Es funktioniert nicht". Gutes Feedback: "Ich habe die Befehle wörtlich ausprobiert, und es wartet nur für immer. Ich habe stdout/stderr überprüft und es druckt' bash: nc: command not found'. Wie kann ich das lösen? " oder "Ich habe es versucht, und es wartet ewig. Allerdings ist die Datenbank aktiv und akzeptiert Verbindungen, und netstat zeigt es zuhören:' tcp 0 192.168.1.17:27017 0.0.0.0:* LISTEN'. Was könnte das Problem sein? " (In diesen Fällen würden Sie netcat installieren oder per lan ip anstelle von localhost verbinden) –

+0

ich entschuldige mich für eine vorschnelle Antwort. Ich habe den Befehl wörtlich ausprobiert und es hat sich als Endlosschleife erwiesen. d. h. egal, wie der Zustand des Mongod-Prozesses war, die Schleife lief weiter. –

1

Während Toms Antwort in den meisten Situationen recht gut funktioniert, kann es fehlschlagen, wenn Sie Ihr Skript mit dem -e Flag ausführen. Ich meine, Sie laufen Ihr Skript mit set -e ganz oben. Warum? Da Toms Antwort auf dem Exit-Status des vorherigen Befehls beruht, wird in diesem Fall grep -q fehlschlagen, wenn die erforderliche Zeichenfolge nicht gefunden wird und daher das gesamte Skript fehlschlägt. Die -e Flagge Dokumentation gibt einen Hinweis, wie Sie dieses Problem zu vermeiden:

Die Schale wird nicht beendet, wenn der Befehl, der unmittelbar Teil der Befehlsliste versagt ist nach einer Weile oder bis Stichwort, Teil den Test in einer if-Anweisung Teil eines Befehls, der in einem & & oder || ausgeführt wird Liste mit Ausnahme des Befehls nach dem letzten & & oder ||, einem beliebigen Befehl in einer Pipeline, aber der letzte, oder wenn der Rückgabestatus des Befehls ist invertiert mit!.

Eine Lösung besteht also darin, den grep-Befehl Teil der while-Bedingung zu machen. Da er jedoch mongodb mit der Option --logappend ausführt, könnte die Suchzeichenfolge als Ergebnis eines vorherigen Laufs angezeigt werden.Ich kombiniert, dass andere Kerl Antwort mit Tom Antwort und es funktioniert wirklich gut:

# Wait until mongo logs that it's ready (or timeout after 60s) 
COUNTER=0 
while !(nc -z localhost 27017) && [[ $COUNTER -lt 60 ]] ; do 
    sleep 2 
    let COUNTER+=2 
    echo "Waiting for mongo to initialize... ($COUNTER seconds so far)" 
done 

Ich finde, dass Kater mit die beste Lösung ist, weil es prüft eigentlich, wenn es etwas hören ist.

+0

Dies ist ein Gewinner. Vielen Dank. – tofutim

1

Eine Lösung mit MongoDB-Tools. Nützlich in einem Docker-Container oder ähnlichem, wo Sie nicht installieren möchten nc.

until mongo --eval "print(\"waited for connection\")" 
    do 
    sleep 60 
    done 

Basierend auf der Antwort des anderen Kerls.

Verwandte Themen