Użycie Internet Explorera do wywołania PHP / CURL dla długo działającego interfejsu API danych powoduje zawieszenie się serwera Apache 2 i wymaga ponownego uruchomienia

10

Korzystam z programu PHP, który działa dobrze, o ile nie jest wywoływany przez przeglądarkę Microsoft Internet Explorer, po czym odradza poniższe procesy, blokuje Apache 2 i wymaga ponownego uruchomienia serwera WWW (na Ubuntu 12.04 LTS).

bob@drools:/etc/php5/apache2# ps auxwww | grep apache2
root      8737  0.1  2.5 369164 25800 ?        Ssl  12:41   0:00 /usr/sbin/apache2 -k start
www-data  8743  0.0  3.2 393748 33268 ?        Sl   12:41   0:00 /usr/sbin/apache2 -k start
www-data  8755  0.1  3.3 393856 33904 ?        Sl   12:41   0:00 /usr/sbin/apache2 -k start
www-data  8779  0.1  3.2 393724 33252 ?        Sl   12:45   0:00 /usr/sbin/apache2 -k start
www-data  8782  0.1  3.2 393716 33236 ?        Sl   12:45   0:00 /usr/sbin/apache2 -k start
www-data  8785  0.1  3.2 393684 33204 ?        Sl   12:45   0:00 /usr/sbin/apache2 -k start
www-data  8812  1.1  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8815  1.3  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8818  1.3  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8821  1.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8824  1.4  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8827  1.4  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8830  1.4  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8835  2.5  3.2 393684 33256 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8838  2.8  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8841  2.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8844  2.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8847  3.2  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8850  3.0  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8853  3.2  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8856  3.2  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8861  3.3  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8864  3.6  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8867  3.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8870  3.6  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8873  3.6  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8876  3.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8879  3.3  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8881  3.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8883  3.6  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8886  3.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8891  3.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8894  3.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8896  3.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8900  3.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8901  3.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8904  3.5  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8909  3.8  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8912  3.8  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8915  3.8  3.2 393684 33264 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
www-data  8918  3.6  3.2 393684 33260 ?        Sl   12:47   0:00 /usr/sbin/apache2 -k start
root      8922  0.0  0.1   9396  2000 pts/0    S+   12:47   0:00 grep --color=auto apache2

Kiedyś blokował cały serwer, dopóki nie zmieniłem niektórych parametrów modułu „ mpm_ ” na coś bardziej sensownego w /etc/spache2/apache2.conf .

Biorąc pod uwagę problemy z programem Internet Explorer, dodałem nawet ten wiersz:

**" SetEnvIf User-Agent ".*MSIE.*"   nokeepalive "**

w pliku wirtualnych hostów znajdującym się tutaj: / etc / apache2 / sites-available.

Jest wiele artykułów na ten temat, ale nie udało mi się zrealizować żadnego z nich:

Serwer Apache 2 zawiesza się po otrzymaniu żądań z IE 10/11 :

Więcej prac badawczo-rozwojowych: Internet Explorer 10 (Windows 8) ulega awarii Apache

Program PHP używa cURL do pobrania listy 25 elementów i wykonania wywołania API (GET) dla każdego z nich na zewnętrzny serwer, który zwraca dane JSON do dalszego przetwarzania. To klasyczny, długo działający program danych.

To, co sprawia, że ​​mój kluski, działa dobrze w każdej innej przeglądarce oprócz Internet Explorera - co powoduje, że serwer WWW źle się zachowuje.

Przesłuchałem wymienione prace badawczo-rozwojowe, a następnie niektóre, wdrożyłem sugerowane poprawki, ale nadal otrzymuję takie same przewidywalne, możliwe do odzyskania, problematyczne zachowanie serwera.

Muszę wymyślić, jak zabezpieczyć serwer przed złym zachowaniem, gdy się napotyka, i przeglądarką Internet Explorer wysyłającą te konkretne żądania. Chciałbym przede wszystkim zrozumieć, dlaczego tak się dzieje.

Wszelkie wskazówki, perspektywy, kierunki lub rozwiązania będą mile widziane ...

Oto migawka mojego kodu cURL:

<?php

// *** CURL Init, SetOps, and Execution Statements ****
$ch = curl_init();


// *** Execute the  API call for each part number and store in the Associative Array ****
$index=0;
foreach ($partNumbersArray as $partNum) {

    $MyValue = $partNum;

    $MyUrl = $MyNiinjaBaseURL."/".$APICmd1."/".$MyDataSet."/".$MyValue."?key=".$MyKey."&$"."filter=substringof('".$MyValue."',PartNumbers)";


    // *** cURL SetOpts, and Execution Statements ****
    curl_setopt($ch, CURLOPT_URL, $MyUrl);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
    // curl_setopt($ch, CURLOPT_TIMEOUT, 15);       // <= THIS *never* worked with any reliability ....
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $server_output = curl_exec ($ch);   // <= THIS executes the cURL call and stores the resulting JSON object in the variable '$server_output'

    $niinjaResultsJsonArray[$MyValue] = $server_output;        // Add the JSON object to the Array and index to PartNumber
    $index++;                                                // Increment the index

} // End Execution of NIINJA API Calls

// ** Close the CURL Object and release resources
curl_close ($ch);

?>

Oto strona informacyjna PHP: http://www.versaggi.net/phptest.phtml

ProfVersaggi
źródło
1
Myślę, że musisz jakoś zalogować pełne przychodzące żądania HTTP zarówno z IE, jak i innej przeglądarki, która nie ma problemu, abyśmy mogli je porównać i poszukać różnic. Proszę spojrzeć na to pytanie na jak można to zrobić. Musi być coś, co IE robi z żądaniem HTTP (dodatkowy lub brakujący nagłówek itp.?), Które prowadzi Apache do traktowania go inaczej. Albo to, albo jest na niższym poziomie (pakiety IP), co na pewno nie mam nadziei.
Stijn de Witt
Mam nadzieję, że pomogę ci zwrócić uwagę na twoje pytanie.
Stijn de Witt
2
Zastanawiając się nad tym, prawdopodobnie mógłbyś to zgłosić Apache jako błąd ... Ponieważ tak naprawdę nie ma sposobu, abym to wytłumaczył jako błąd Apache. Może to również pomóc ci zdobyć bardzo doświadczonych guru Apache, którzy spojrzą na problem (i mam nadzieję, że to naprawią). Jeśli chcesz pójść tą drogą, pomocne może być zmniejszenie strony, na której występuje problem, do najmniejszego możliwego scenariusza, który wciąż powoduje problem. To i tak może być pomocne samo w sobie.
Stijn de Witt
Ustaw limit czasu w zawijaniu za pomocą setopt
user1050544
3
Czy klient ma wpływ na to, które adresy URL są otwierane przez skrypt php? Czy żądania cURL nadal trwają, gdy znajdziesz serwer w powyższym stanie? Czy to możliwe, że IE ponawia żądania, gdy odpowiadają zbyt wolno? Jeśli każde żądanie HTTP do twojego serwera WWW może spowodować zainicjowanie kolejnych 25 żądań HTTP do backendu, może to nastąpić dość szybko. Czy mógłbyś ponownie użyć odpowiedzi otrzymanych za pomocą cURL dla więcej niż jednego klienta?
kasperd

Odpowiedzi:

5

Dawno temu widziałem blokady Apache wynikające z procesu Apache wywołującego przez HTTP inny adres URL obsługiwany przez proces Apache na tym samym serwerze. Czasami kończyłem się z szeregiem procesów oczekujących na takie połączenia bez dostępnych procesów Apache do ich obsługi. W moim przypadku miałem warstwę tłumaczącą przed niektórymi stronami internetowymi, ale wywołanie interfejsu API we własnej witrynie jest bardzo podobne.

Charakterystyka przeglądarki wykonującej pierwotne wywołanie może zwiększyć to prawdopodobieństwo. Na przykład utrzymywanie aktywności, zachowanie przekroczenia limitu czasu itd., Ale nie jest to wina przeglądarki.

Jeśli jest coś podobnego do tego, co widziałem, to chcesz spojrzeć na zachowanie limitu czasu podczas używania curl. Podany kod sugeruje, że się nad tym zastanawiasz, ale być może będziesz musiał być bardziej szczegółowy w swoim zrozumieniu, do którego punktu żądania jest kierowany. Interesujące może być obejrzenie go za pomocą tcpdump (lub ngrep, Wireshark lub cokolwiek innego). Dobrze byłoby również wiedzieć, jakie wywołanie systemowe jest w toku, gdy proces wywoływania się zawiesi. Spójrz na to z strace -p [PID].

Prawdopodobnie powinieneś także zastanowić się, czy możesz usunąć połączenie HTTP z używania interfejsu API. Czy potrafisz utrzymać wszystko w ramach tego samego procesu Apache, wykonując bezpośrednie wywołanie odpowiedniego kodu, który obsługuje żądanie API?

Prawdopodobnie warto powiedzieć innym, jak korzystasz z PHP (np. Mod_php, fpm itp.). Może to być częścią zrozumienia mechanizmu blokowania kodu.

Mc0e
źródło
Może to pomóc w przesłuchaniu wewnętrznych elementów PHP ... versaggi.net/phptest.phtml
ProfVersaggi
W ramach eksperymentu wyłączyłem wywołania API z pętli CURL i przeprowadziłem szereg testów. To odizolowało problem, ponieważ podczas tych testów deamon Apache2 pozostał zdrowy.
ProfVersaggi