2013-05-15 9 views
5

Mein Entwicklungsteam hat Probleme beim Zugriff auf eine entfernte MongoDB-Datenbank aus ihren lokalen Entwicklungsumgebungen.MongoDB PHP-Headerdaten-Timeout

Der entfernte Ubuntu Entwicklungsserver führt die neueste Version 2.4.3 von MongoDB und PHP 5.3 mit dem mongo-php-Treiber v1.3.7 für PHP 5.3. mongodb.conf ist fast leer mit Ausnahme des grundlegenden Pfades. Derzeit sind keine Shards oder Replikatgruppen vorhanden.

Alle Teammitglieder verwenden OSX 10.8, PHP 5.3 und den mongo-php-Treiber v1.3.7 für PHP 5.3. Einige Teammitglieder verwenden XAMPP, andere verwenden den integrierten OSX AMP-Stack. Wir testen auf allen gängigen Desktop-Browsern.

Jedes Mal, wenn eine Seite benötigt Daten von Mongo zu greifen beginnen wir mit dieser Verbindung Aufruf der Funktion:

public static function connect($server, $db) 
{ 
    $connection = new MongoClient(
     "mongodb://{$server}:27017", 
     array(
      "connectTimeoutMS" => 20000, 
      "socketTimeoutMS" => 20000 
     ) 
    ); 

    return $connection->$db; 
} 

jedoch fast 30% der Seite geladen wird erleben den folgenden Fehler:

Failed to connect to: www.development-server.com:27017: send_package: error reading from socket: Timed out waiting for header data

Es scheint, dass ein großer Teil dieser Fehler beim Aktualisieren einer Seite auftritt, anstatt zu einer neuen Seite zu navigieren, aber das ist mehr eine Vermutung als eine Tatsache. Ich habe alle php.ini Datei überprüft und bestätigt, dass default_socket_timeout = 60 festgelegt ist.

Der Entwicklungsserver beherbergt auch eine Kopie der Website, hat aber nie den Fehler ausgelöst, vermutlich da es nur localhost ruft dorthin zu gelangen. Wenn ich MongoDB lokal installierte, gingen auch die Fehler weg.

Dies scheint wirklich ein Timeout-Problem zu sein, aber ich kann keine weiteren Einstellungen, Parameter oder Konfigurationen finden, um den Ablaufzeitraum anzupassen. Sind da irgendwelche?

+0

Ist es möglich, zu überprüfen, während solche Probleme war die Verbindung von mongod Prozess akzeptiert. Sie können dies in Mongo-Logs überprüfen. Das Protokoll wird wie folgt aussehen: „Do 16 06.31.47 May [initandlisten] Verbindung angenommen von 127.0.0.1:49621 # 35 (2 Anschlüssen jetzt offen)“ Ebenso finden Sie eine Log-Zeile, wenn die Verbindung geschlossen zu werden.Ich möchte überprüfen, ob die Verbindung von mongoDB geehrt wird oder die Box nicht erreicht. –

+0

Ich sehe das in den Protokollen; Wenn ich zum ersten Mal eine Seite lade, sehe ich die Verbindung 'Wed May 15 21: 59: 25.001 [initandlisten] Verbindung akzeptiert von ip_adresse: 50238 # 411 (20 Verbindungen jetzt geöffnet)' dann machen alle folgenden Seitenladevorgänge keinen Protokolleintrag und Seiten laden gut. An einem zufälligen Punkt kann die Seite nicht geladen werden und ich sehe 'Wed 15. Mai 21: 59: 44.914 [conn401] Endverbindung ip_address: 49819 (19 Verbindungen jetzt geöffnet)'. Manchmal sehe ich eine zweite Verbindung akzeptieren, ohne eine Endverbindung, die folgende Seite wird dann fehlschlagen und zeigen die Endverbindung. – andvari101

Antwort

0

versuchen, ohne den Anschluss in Verbindung verbinden oder

array( "connectTimeoutMS" => -1, "socketTimeoutMS" => -1 )

(Endlos-Timeout)

+0

Das Festlegen der Zeitlimits auf unendlich (oder sogar sehr sehr groß) scheint zu funktionieren, aber Anfragen dauern eine Minute oder länger. – andvari101

1

Die Antwort von @hernan_arg gesetzt hat mich über eine andere Möglichkeit zu denken. Anstatt sich auf die ein-und-nur Verbindungsversuch erfolgreich zu sein (was ewig zu dauern scheint), ist es akzeptabel, die Verbindung in einer Schleife zu halten, bis es gelingt?

public static function connect($server, $db) 
{ 
    $connection = null; 

    try { 
     $connection = new MongoClient("mongodb://{$server}"); 
    } catch (MongoConnectionException $e) { 
     return self::connect(); 
     exit; 
    } 

    return $connection->$db; 
} 

Logging zeigt an, dass, wenn die Verbindung nicht funktioniert, ist es nicht schnell, und die Schleife wird eine neue Verbindung in einem viel zügiger als die unendliche Timeout tut etablieren. Angenommen, die Datenbank ist nicht erreichbar, gehe ich davon aus, dass ich mich auf das PHP-Ausführungstimeout verlassen kann, um den Prozess schließlich zu beenden.

0

Die 1.4.1 Release des Treibers beheben einige Stabilitätsprobleme über instabile Netze.

Angenommen, Sie sprechen mit einem Replicaset, wird der Treiber Server, die unangemessen langsam sind verwerfen - anstatt erneut versuchen, eine Verbindung herzustellen, wird der Treiber jetzt für wenige Sekunden Blacklist, ohne diese Ausnahmen bei der Verbindung zu werfen (vorausgesetzt, wir können eine Verbindung zu einem Server atleast)