Usando o IE para invocar PHP / CURL para API de dados de longa execução faz com que o servidor Apache2 congele e exija reinicialização

9

Estou executando um programa PHP que funciona bem, desde que não seja invocado por um navegador Microsoft IE , após o qual ele gera os processos abaixo, bloqueia o Apache2 e requer um reinício do servidor web (no Ubuntu 12.04LTS).

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

Ele costumava bloquear todo o servidor até que eu alterasse alguns dos parâmetros do módulo " mpm _ " para algo mais razoável em /etc/spache2/apache2.conf .

Dados os problemas com o IE, eu adicionei esta linha:

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

no arquivo de hosts virtuais localizado aqui: / etc / apache2 / sites-available.

Há vários artigos escritos sobre o assunto, mas não tive sucesso em implementar nenhum deles:

Apache Server2 trava após receber solicitações do IE 10/11: link

Mais R & D: link

O programa PHP usa cURL para obter uma lista de 25 itens e executar uma chamada de API (GET) para cada um em um servidor externo que retorna dados JSON para processamento adicional. É um programa clássico de dados de longa duração.

O que faz meu macarrão é que ele funciona bem em todos os outros navegadores, exceto no IE - o que faz com que o servidor da Web se comporte mal.

Interroguei os R & D listados e, em seguida, alguns, implementei as correções sugeridas, mas ainda obtenho o mesmo comportamento de servidor previsível, recreatável e problemático.

O que eu preciso fazer é descobrir como proteger o servidor de se comportar mal quando ele se depara com o navegador IE e fazer essas solicitações particulares dele. O que eu gostaria de fazer é entender por que isso acontece em primeiro lugar.

Qualquer orientação, perspectivas, direção ou soluções seriam muito apreciadas ...

EDITAR:

Aqui está um instantâneo do meu 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 SetOps, 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); 

?>

Aqui está a página PHP INFO: link

    
por ProfVersaggi 25.07.2014 / 18:55

1 resposta

5

Há muito tempo vi travamentos do apache resultantes de um processo do apache fazendo uma chamada via http para outro URL atendido por um processo do apache no mesmo servidor. Eu às vezes acabo com um monte de processos esperando em tais chamadas sem processos apache disponíveis para atendê-los. No meu caso, eu tinha uma camada de tradução na frente de algumas páginas da web, mas chamar uma API em seu próprio site é a mesma coisa.

As características do navegador que faz a chamada original podem tornar isso mais provável. por exemplo, keep-alive, timeout e assim por diante, mas não é fundamentalmente o navegador com defeito.

Se é algo parecido com o que eu vi, você quer observar o comportamento de tempo limite no uso de curl. O código que você incluiu sugere que você inclua isso, mas talvez seja necessário ter mais detalhes sobre o ponto exato da solicitação. Pode ser interessante vê-lo com o tcpdump (ou ngrep, wireshark ou qualquer outro). Também seria bom saber qual chamada de sistema está em andamento quando o processo de chamada é interrompido. ou seja, olhe para ele com strace -p [PID] .

Você provavelmente também deve estar pensando se pode remover a chamada http do uso da API. Você pode manter as coisas dentro do mesmo processo do apache fazendo uma chamada direta para o código apropriado que lida com a solicitação da API?

É provavelmente relevante dizer às pessoas como você está executando o PHP (por exemplo, mod_php, fpm, etc). Isso pode ser parte da compreensão do mecanismo pelo qual o código trava.

    
por 30.07.2014 / 08:36