Die Verwendung von Internet Explorer zum Aufrufen von PHP / CURL für eine lange laufende Daten-API führt dazu, dass der Apache 2-Server einfriert und neu gestartet werden muss

10

Ich führe ein PHP-Programm aus, das einwandfrei funktioniert, solange es nicht von einem Microsoft Internet Explorer-Browser aufgerufen wird. Danach werden die folgenden Prozesse ausgelöst, Apache 2 wird gesperrt und der Webserver muss neu gestartet werden (unter 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

Früher wurde der gesamte Server gesperrt, bis ich einige der Parameter des Moduls " mpm_ " in /etc/spache2/apache2.conf in einen vernünftigeren Wert geändert habe .

Angesichts der Probleme mit Internet Explorer habe ich sogar folgende Zeile hinzugefügt:

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

in der Datei für virtuelle Hosts, die sich hier befindet: / etc / apache2 / sites-available.

Es gibt eine Reihe von Artikeln zu diesem Thema, aber ich hatte keinen Erfolg bei der Implementierung:

Apache Server 2 hängt nach dem Empfang von Anforderungen vom IE 10/11 :

Weitere Forschungs- und Entwicklungsarbeiten: Internet Explorer 10 (Windows 8) stürzt Apache ab

Das PHP-Programm verwendet cURL , um eine Liste von 25 Elementen zu erstellen und für jedes Element einen (GET) API-Aufruf an einen externen Server durchzuführen, der JSON-Daten zur weiteren Verarbeitung zurückgibt. Es ist ein klassisches Datenprogramm mit langer Laufzeit.

Was meine Nudel backt, ist, dass sie in jedem anderen Browser außer Internet Explorer einwandfrei funktioniert - was dazu führt, dass sich der Webserver schlecht verhält.

Ich habe die aufgelisteten Forschungs- und Entwicklungsarbeiten abgefragt und dann einige die vorgeschlagenen Korrekturen implementiert, aber ich erhalte immer noch das gleiche vorhersehbare, wiederherstellbare und problematische Serververhalten.

Ich muss herausfinden, wie ich den Server vor schlechtem Verhalten schützen kann, wenn er auf etwas trifft, und der Internet Explorer-Browser diese speziellen Anforderungen an ihn stellt. Ich würde gerne verstehen, warum es überhaupt passiert.

Jede Anleitung, Perspektive, Richtung oder Lösung wäre sehr dankbar ...

Hier ist eine Momentaufnahme meines cURL-Codes:

<?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);

?>

Hier ist die PHP-Informationsseite: http://www.versaggi.net/phptest.phtml

ProfVersaggi
quelle
1
Ich denke, Sie müssen irgendwie die vollständigen eingehenden HTTP-Anforderungen sowohl vom IE als auch von einem anderen Browser protokollieren, der kein Problem hat, damit wir sie vergleichen und nach Unterschieden suchen können. Bitte schauen Sie sich diese Frage an, wie Sie das tun können. Es muss etwas geben, das der IE mit der HTTP-Anfrage macht (ein zusätzlicher oder fehlender Header usw.?), Was Apache dazu veranlasst, sie anders zu behandeln. Entweder das, oder es liegt auf einer niedrigeren Ebene (IP-Pakete), was ich sicher nicht hoffe.
Stijn de Witt
Ich habe ein Kopfgeld darauf gelegt, um Ihnen hoffentlich zu helfen, etwas Aufmerksamkeit für Ihre Frage zu bekommen.
Stijn de Witt
2
Wenn Sie noch etwas darüber nachdenken, könnten Sie dies wahrscheinlich Apache als Fehler melden ... Da ich dies auf keinen Fall als keinen Apache-Fehler erklären kann. Dies könnte Ihnen auch dabei helfen, einige sehr erfahrene Apache-Gurus dazu zu bringen, sich das Problem anzusehen (und es hoffentlich zu beheben). Wenn Sie diesen Weg gehen möchten, kann es hilfreich sein, wenn Sie die Seite, auf der das Problem auftritt, auf das kleinstmögliche Szenario verkleinern, in dem das Problem weiterhin besteht. Dies kann an und für sich sowieso hilfreich sein.
Stijn de Witt
Stellen Sie eine Zeitüberschreitung in Curl mit setopt
user1050544
3
Hat der Client einen Einfluss darauf, auf welche URLs das PHP-Skript zugreift? Sind die cURL-Anforderungen noch aktiv, wenn Sie den Server im obigen Status finden? Könnte es sein, dass der IE die Anforderungen wiederholt, wenn sie zu langsam antworten? Wenn jede HTTP-Anforderung an Ihren Webserver dazu führen kann, dass weitere 25 HTTP-Anforderungen an ein Backend initiiert werden, kann dies recht schnell eskalieren. Könnten Sie die Antworten, die Sie mit cURL erhalten, für mehr als einen Client wiederverwenden?
Kasperd

Antworten:

5

Vor langer Zeit sah ich Apache-Abstürze, die sich aus einem Apache-Prozess ergaben, der über HTTP eine andere URL anrief, die von einem Apache-Prozess auf demselben Server bedient wurde. Manchmal hatte ich eine Reihe von Prozessen, die auf solche Anrufe warteten, ohne dass Apache-Prozesse verfügbar waren, um sie zu bedienen. In meinem Fall hatte ich eine Übersetzungsebene vor einigen Webseiten, aber das Aufrufen einer API auf Ihrer eigenen Website ist fast dasselbe.

Die Eigenschaften des Browsers, der den ursprünglichen Anruf tätigt, können die Wahrscheinlichkeit erhöhen, dass dies auftritt. Zum Beispiel Keep-Alive, Timeout-Verhalten usw., aber im Grunde ist der Browser nicht schuld.

Wenn es etwas mit dem zu tun hat, was ich gesehen habe, möchten Sie das Timeout-Verhalten bei der Verwendung von Curl untersuchen. Der Code, den Sie eingefügt haben, deutet darauf hin, dass Sie damit einverstanden sind, aber Sie müssen möglicherweise genauer verstehen, zu welchem ​​Punkt in der Anfrage es kommt. Es könnte interessant sein, es mit tcpdump (oder ngrep, Wireshark oder was auch immer) zu betrachten. Es wäre auch gut zu wissen, welcher Systemaufruf ausgeführt wird, wenn der aufrufende Prozess hängt. Das heißt, schau es dir an mit strace -p [PID].

Sie sollten wahrscheinlich auch darüber nachdenken, ob Sie den HTTP-Aufruf aus Ihrer Verwendung der API entfernen können. Können Sie die Dinge innerhalb desselben Apache-Prozesses halten, indem Sie direkt den entsprechenden Code aufrufen, der die API-Anforderung verarbeitet?

Es ist wahrscheinlich wichtig, den Leuten zu sagen, wie Sie PHP ausführen (z. B. mod_php, fpm usw.). Dies kann Teil des Verständnisses des Mechanismus sein, durch den der Code blockiert.

mc0e
quelle
Dies könnte bei der Abfrage der PHP-Interna helfen
ProfVersaggi
Als Experiment habe ich die API-Aufrufe aus der CURL-Schleife deaktiviert und eine Reihe von Tests durchgeführt. Dies isolierte das Problem, da Apache2 Deamon während dieser Tests gesund blieb.
ProfVersaggi