2013-05-15 17 views
5

Mój zespół programistów ma problemy z dostępem do zdalnej bazy danych MongoDB ze swoich lokalnych środowisk programistycznych.Limit czasu nagłówka PHP MongoDB

Zdalny serwer deweloperski Ubuntu zawiera najnowszy v2.4.3 MongoDB i PHP 5.3 z mongo-php-driver v1.3.7 zbudowany na PHP 5.3. mongodb.conf jest prawie pusty, z wyjątkiem podstawowej konfiguracji ścieżki. Obecnie nie ma żadnych shardów ani zestawów replik.

Wszyscy członkowie zespołu używają OSX 10.8, PHP 5.3 i mają wbudowany sterownik mongo-php w wersji 1.3.7 dla PHP 5.3. Niektórzy członkowie zespołu używają XAMPP, inni używają wbudowanego stosu AMP OSX. Testujemy we wszystkich głównych przeglądarkach komputerowych.

Ilekroć strona musi pobrać dane z Mongo, możemy uruchomić poprzez wywołanie tej funkcji połączenia:

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

    return $connection->$db; 
} 

Jednak prawie 30% od strony obciążenia występują następujący błąd:

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

Wygląda na to, że znaczna część tych błędów pojawia się podczas odświeżania strony, a nie w celu przejścia do nowej strony, ale to raczej domysły niż fakt. Sprawdziłem każdy plik php.ini i potwierdziłem, że ustawiono default_socket_timeout = 60.

Serwer deweloperski obsługuje również kopię witryny, ale nigdy nie wyrzucił błędu, prawdopodobnie dlatego, że wywołuje tylko localhost, aby się tam dostać. Kiedy zainstalowałem MongoDB lokalnie, błędy również zniknęły.

To naprawdę wydaje się być problem z limitem czasu, ale nie mogę znaleźć żadnych dalszych ustawień, parametrów ani konfiguracji, aby dostosować okres wygaśnięcia. Czy są jakieś?

+0

Czy można sprawdzić, czy podczas takich problemów było połączenie akceptowane przez proces mongody. Możesz to sprawdzić w dziennikach mongo. Dziennik będzie wyglądał następująco: "Czw 16 maja 06:31:47 [initandlisten] połączenie zaakceptowane z 127.0.0.1:49621 # 35 (teraz otwierają się 2 połączenia)" Podobnie otrzymasz linię dziennika, jeśli połączenie się zamyka.Chcę sprawdzić, czy połączenie jest honorowane przez mongoDB lub nie dociera do tego pola. –

+0

Widzę to w dziennikach; kiedy początkowo ładuję stronę po raz pierwszy, widzę połączenie "Śr 15 maja 21: 59: 25.001 [initandlisten] połączenie zaakceptowane z adresu ip: 50238 # 411 (20 połączeń teraz otwarte)" następnie wszystkie kolejne ładowanie stron nie powoduje wpisu dziennika strony ładują się dobrze. W pewnym losowym punkcie strona nie ładuje się i widzę 'Wed 15 maja 21: 59: 44.914 [conn401] koniec połączenia ip_address: 49819 (19 połączeń teraz otwartych)'. Czasami widzę, że drugie połączenie akceptuje się bez połączenia końcowego, a następnie ładowanie strony zakończy się niepowodzeniem i wyświetli połączenie końcowe. – andvari101

Odpowiedz

0

spróbować połączyć bez portu w związku lub ustawić

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

(nieskończony timeout)

+0

Ustawienie limitów czasu na nieskończone (lub nawet bardzo duże) wydaje się działać, ale żądania będą trwać minutę lub dłużej. – andvari101

1

Reakcja @hernan_arg dało mi do myślenia o innej możliwości. Zamiast polegać na próbie połączenia tylko jeden raz (co wydaje się trwać wiecznie), czy dopuszczalne jest podłączenie połączenia w pętli, dopóki się nie uda?

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 wskazuje, że gdy połączenie nie powiedzie, to nie szybko i pętla będzie nawiązać nowe połączenie w znacznie bardziej terminowo niż nieskończony limit czasu robi. Przypuśćmy, że baza danych staje się nieosiągalna Zakładam, że mogę polegać na timeoutie wykonania PHP, aby ostatecznie zabić proces.

0

Wersja 1.4.1 sterownika rozwiązuje niektóre problemy ze stabilnością w niestabilnych sieciach.

Zakładając, że rozmawiasz z repliką, sterownik odrzuci serwery, które są nierozsądnie wolne - zamiast ponownie spróbować połączyć się z nimi, sterownik będzie teraz zamieniał go na czarną listę przez kilka sekund bez odrzucania tych wyjątków podczas połączenia (zakładając, że możemy połączyć się z co najmniej jednym serwerem)