El uso de Internet Explorer para invocar PHP / CURL para la API de datos de larga ejecución hace que el servidor Apache 2 se congele y requiera reiniciar

10

Estoy ejecutando un programa PHP que funciona bien siempre que no sea invocado por un navegador Microsoft Internet Explorer, después de lo cual genera los siguientes procesos, bloquea Apache 2 y requiere un reinicio del servidor web (en 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

Solía ​​bloquear todo el servidor hasta que cambié algunos de los parámetros del módulo " mpm_ " a algo más razonable en /etc/spache2/apache2.conf .

Dados los problemas con Internet Explorer, incluso he agregado esta línea:

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

en el archivo de hosts virtuales ubicado aquí: / etc / apache2 / sites-available.

Hay varios artículos escritos sobre el tema, pero no he tenido éxito implementando ninguno de ellos:

Apache Server 2 se cuelga después de recibir solicitudes de IE 10/11 :

Más I + D: Internet Explorer 10 (Windows 8) que bloquea Apache

El programa PHP usa cURL para tomar una lista de 25 elementos y realizar una llamada API (GET) para cada uno a un servidor externo que devuelve datos JSON para su posterior procesamiento. Es un programa de datos clásico de larga ejecución.

Lo que hornea mi fideo es que funciona bien en cualquier otro navegador, excepto Internet Explorer, lo que hace que el servidor web se comporte mal.

He interrogado las actividades de I + D que figuran en la lista y luego algunas, he implementado las soluciones sugeridas, pero sigo teniendo el mismo comportamiento predecible, recreable y problemático del servidor.

Necesito descubrir cómo proteger el servidor para que no se comporte mal cuando se encuentre y que el navegador Internet Explorer haga estas solicitudes particulares. Me gustaría entender por qué sucede en primer lugar.

Cualquier orientación, perspectiva, dirección o solución sería muy apreciada ...

Aquí hay una instantánea de mi código 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);

?>

Aquí está la página de información de PHP: http://www.versaggi.net/phptest.phtml

ProfVersaggi
fuente
1
Creo que necesita registrar de alguna manera las solicitudes HTTP entrantes completas tanto de IE como de algún otro navegador que no tenga un problema para que podamos compararlas y buscar diferencias. Eche un vistazo a esta pregunta sobre cómo puede hacer eso. Debe haber algo que IE haga con la solicitud HTTP (¿algún encabezado adicional o faltante, etc.?) Que lleve a Apache a tratarlo de manera diferente. O eso, o está en un nivel más bajo (paquetes IP), lo que seguro no espero.
Stijn de Witt
Pongo una recompensa para ayudarlo a obtener un poco de atención a su pregunta.
Stijn de Witt
2
Pensando un poco más, probablemente podría informar esto a Apache como un error ... Porque realmente no hay forma de que pueda explicar esto como un error de Apache. Eso también podría ayudarlo a obtener algunos gurús de Apache con mucha experiencia para ver el problema (y con suerte solucionarlo). Si desea seguir esa ruta, podría ayudar si reduce la página que experimenta el problema al escenario más pequeño posible que todavía tiene el problema. De todos modos, esto puede ser útil en sí mismo.
Stijn de Witt
Establecer un tiempo de espera en curl usando setopt
user1050544
3
¿El cliente tiene alguna influencia sobre las URL a las que accede el script php? ¿Las solicitudes de cURL siguen en curso cuando encuentra el servidor en el estado anterior? ¿Podría ser que IE está volviendo a intentar las solicitudes cuando responden demasiado lento? Si cada solicitud HTTP a su servidor web puede hacer que inicie otras 25 solicitudes HTTP a un servidor, eso puede escalar rápidamente. ¿Podría reutilizar las respuestas que obtiene con cURL para más de un cliente?
kasperd

Respuestas:

5

Hace mucho tiempo, vi bloqueos de Apache como resultado de un proceso de Apache que realiza una llamada a través de HTTP a otra URL atendida por un proceso de Apache en el mismo servidor. A veces terminé con un montón de procesos esperando tales llamadas sin procesos de Apache disponibles para atenderlos. En mi caso, tenía una capa de traducción frente a algunas páginas web, pero llamar a una API en su propio sitio es casi lo mismo.

Las características del navegador que realiza la llamada original podrían hacer que esto sea más probable. Por ejemplo, mantener vivo, tiempo de espera, etc., pero no es fundamentalmente el navegador el culpable.

Si se parece a lo que vi, entonces querrás estar observando el comportamiento del tiempo de espera en el uso de curl. El código que ha incluido sugiere que está en eso, pero es posible que deba ser más específico para comprender exactamente a qué punto de la solicitud llega. Puede ser interesante mirarlo con tcpdump (o ngrep, Wireshark o lo que sea). También sería bueno saber qué llamada del sistema está en progreso cuando se bloquea el proceso de llamada. Es decir, míralo con strace -p [PID].

Probablemente también debería estar pensando si puede eliminar la llamada HTTP de su uso de la API. ¿Puede mantener las cosas dentro del mismo proceso de Apache haciendo una llamada directa al código apropiado que maneja la solicitud de API?

Probablemente sea relevante decirle a la gente cómo está ejecutando PHP (por ejemplo, mod_php, fpm, etc.). Eso puede ser parte de comprender el mecanismo por el cual el código se bloquea.

mc0e
fuente
Esto podría ayudar con la interrogación de las partes
ProfVersaggi
Como experimento, deshabilité las llamadas a la API del bucle CURL y ejecuté un montón de pruebas. Eso aisló el problema ya que durante esas pruebas, el demonio Apache2 se mantuvo saludable.
ProfVersaggi