AKTUALISIEREN :Unser Support-Artikel zu diesem Thema (im Wesentlichen eine Kopie dieses Beitrags) wurde in unser Dokument zur Fehlerbehebung bei Verbindungen verschoben.
Es gibt ein bekanntes Problem, bei dem das Azure IaaS-Netzwerk ein Leerlaufzeitlimit von etwa dreizehn Minuten erzwingt (empirisch ermittelt). Wir arbeiten mit Azure zusammen, um zu sehen, ob wir die Dinge nicht benutzerfreundlicher machen können, aber in der Zwischenzeit hatten andere Erfolg, indem sie ihre Treiberoptionen konfigurierten, um das Problem zu umgehen.
Maximale Leerlaufzeit der Verbindung
Die effektivste Problemumgehung, die wir bei der Zusammenarbeit mit Azure und unseren Kunden gefunden haben, bestand darin, die maximale Verbindungsleerlaufzeit auf weniger als vier Minuten festzulegen. Die Idee ist, den Treiber dazu zu bringen, inaktive Verbindungen zu recyceln, bevor die Firewall das Problem erzwingt. Beispielsweise hat ein Kunde, der den C#-Treiber verwendet, MongoDefaults.MaxConnectionIdleTime
festgelegt auf eine Minute und es klärte ihre Probleme auf.
MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);
Der Anwendungscode selbst hat sich nicht geändert, aber jetzt recycelt der Treiber im Hintergrund ungenutzte Verbindungen aggressiv. Das Ergebnis ist auch in den Serverprotokollen zu sehen:viele Verbindungsabbrüche während Leerlaufzeiten in der App.
Weitere Einzelheiten zu diesem Ansatz finden Sie im verwandten Mongo-User-Thread SocketException using C# driver on azure.
Keepalive
Sie können das Problem auch umgehen, indem Sie Ihre Verbindungen mit einer Art Keepalive weniger untätig machen. Dies ist ein wenig schwierig zu implementieren, es sei denn, Ihr Treiber unterstützt es standardmäßig, normalerweise durch Nutzung von TCP Keepalive. Wenn Sie Ihre eigene rollen müssen, stellen Sie sicher, dass Sie alle paar Minuten jede inaktive Verbindung aus dem Pool holen und einen einfachen und billigen Befehl ausgeben, wahrscheinlich einen Ping.
Behandlung von Verbindungsabbrüchen
Auch ohne ein aggressives Firewall-Setup kann es von Zeit zu Zeit zu Verbindungsabbrüchen kommen. Bevor Sie mit der Produktion beginnen, möchten Sie sicher sein, dass sie richtig gehandhabt werden.
Stellen Sie zunächst sicher, dass die automatische Wiederverbindung aktiviert ist. Wie dies zu tun ist, ist von Treiber zu Treiber unterschiedlich, aber wenn der Treiber feststellt, dass ein Vorgang fehlgeschlagen ist, weil die Verbindung schlecht war, wird der Treiber durch Aktivieren der automatischen Wiederverbindung aufgefordert, die Verbindung wiederherzustellen.
Aber das löst das Problem nicht vollständig. Sie haben immer noch das Problem, was mit dem fehlgeschlagenen Vorgang zu tun ist, der die Wiederverbindung ausgelöst hat. Die automatische Wiederverbindung wiederholt fehlgeschlagene Vorgänge nicht automatisch. Das wäre gefährlich, insbesondere für Schreibvorgänge. Daher wird normalerweise eine Ausnahme geworfen und die App wird gebeten, damit umzugehen. Oft ist es ein Kinderspiel, Lesevorgänge erneut zu versuchen. Aber das Wiederholen von Schreibvorgängen sollte sorgfältig überlegt werden.
Die Mongo-Shell-Sitzung unten zeigt das Problem. Die Mongo-Shell hat standardmäßig die automatische Wiederverbindung aktiviert. Ich füge ein Dokument in eine Sammlung namens stuff
ein Suchen Sie dann alle Dokumente in dieser Sammlung. Dann stellte ich einen Timer auf 30 Minuten und versuchte es noch einmal mit demselben Fund. Es schlug fehl, aber die Shell stellte automatisch wieder eine Verbindung her, und als ich meinen Suchvorgang sofort wiederholte, funktionierte es wie erwartet.
% 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") }
Wir sind hier, um zu helfen
Wenn Sie Fragen haben, können Sie sich natürlich gerne unter [email protected] an uns wenden. Wir helfen Ihnen gerne weiter.