Использование Internet Explorer для вызова PHP / CURL для долго работающих API данных приводит к зависанию сервера Apache 2 и требует перезагрузки

10

Я использую программу PHP, которая работает нормально, если она не вызывается браузером Microsoft Internet Explorer, после чего она запускает описанные ниже процессы, блокирует Apache 2 и требует перезагрузки веб-сервера (в 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

Раньше он блокировал весь сервер, пока я не изменил некоторые параметры модуля « mpm_ » на более разумные в /etc/spache2/apache2.conf .

Учитывая проблемы с Internet Explorer, я даже добавил эту строку:

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

в файле виртуальных хостов, расположенном здесь: / etc / apache2 / sites-available.

Есть много статей, написанных по этому вопросу, но я не добился успеха в реализации любой из них:

Apache Server 2 зависает после получения запросов от IE 10/11 :

Больше R & D: Internet Explorer 10 (Windows 8) сбой Apache

Программа PHP использует cURL для получения списка из 25 элементов и выполнения вызова API (GET) для каждого внешнего сервера, который возвращает данные JSON для дальнейшей обработки. Это классическая долгосрочная программа для обработки данных.

Что запекает мою лапшу, так это то, что она отлично работает в любом другом браузере, кроме Internet Explorer, что приводит к неправильной работе веб-сервера.

Я опросил перечисленные НИОКР, а затем некоторые из них, внедрил предложенные исправления, но у меня все еще остается такое же предсказуемое, исправимое, проблемное поведение сервера.

Мне нужно выяснить, как защитить сервер от плохого поведения, когда он сталкивается, и браузер Internet Explorer делает эти конкретные запросы к нему. Я хотел бы понять, почему это происходит в первую очередь.

Любое руководство, перспективы, направления или решения будут с благодарностью ...

Вот снимок моего кода 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);

?>

Вот информационная страница PHP: http://www.versaggi.net/phptest.phtml

ProfVersaggi
источник
1
Я думаю, что вам нужно каким-то образом регистрировать полные входящие HTTP-запросы как из IE, так и из какого-либо другого браузера, у которого нет проблем, чтобы мы могли сравнивать их и искать различия. Пожалуйста, посмотрите на этот вопрос, как вы можете это сделать. Должно быть что-то, что IE делает с HTTP-запросом (какой-то дополнительный или отсутствующий заголовок и т. Д.), Что заставляет Apache обращаться с ним по-другому. Либо так, либо на более низком уровне (IP-пакетов), который, я уверен, не надеюсь.
Стейн де Витт
Я вознаграждаю за это, надеюсь, помочь вам привлечь внимание к вашему вопросу.
Стейн де Витт
2
Подумав об этом, вы могли бы сообщить об этом Apache как об ошибке ... Потому что на самом деле я не могу объяснить это как ошибку Apache. Это также может помочь вам найти очень опытных гуру Apache, которые посмотрят на проблему (и, надеюсь, исправят ее). Если вы хотите пойти по этому пути, это может помочь, если вы сократите страницу, на которой возникла проблема, до наименьшего возможного сценария, который все еще имеет проблему. Это может быть полезно само по себе в любом случае.
Стейн де Витт
Установите таймаут в curl с помощью setopt
user1050544
3
Влияет ли клиент на то, какие URL-адреса используются PHP-скриптом? Запросы cURL все еще продолжаются, когда вы находите сервер в вышеуказанном состоянии? Может ли быть так, что IE повторяет запросы, когда они отвечают слишком медленно? Если каждый HTTP-запрос к вашему веб-серверу может привести к тому, что он инициирует еще 25 HTTP-запросов к бэкэнду, это может быстро возрасти. Не могли бы вы повторно использовать ответы, полученные с помощью cURL, для более чем одного клиента?
Касперд

Ответы:

5

Давным-давно я видел блокировки Apache в результате того, что процесс Apache совершал вызов через HTTP на другой URL, обслуживаемый процессом Apache на том же сервере. Иногда я сталкивался с кучей процессов, ожидающих таких вызовов, когда не было доступных процессов Apache для их обслуживания. В моем случае у меня был слой перевода перед некоторыми веб-страницами, но вызов API на вашем собственном сайте - это почти то же самое.

Характеристики браузера, выполняющего исходный вызов, могут сделать это более вероятным. Например, keep-alive, время ожидания и т. Д., Но это не принципиально виноват браузер.

Если это что-то похожее на то, что я видел, тогда вы хотите посмотреть на поведение при использовании curl. Код, который вы включили, предполагает, что вы на это способны, но вам, возможно, потребуется более детально понять, к какому пункту запроса он относится. Может быть интересно посмотреть на это с помощью tcpdump (или ngrep, Wireshark или чего-то еще). Также было бы полезно узнать, какой системный вызов выполняется, когда зависает вызывающий процесс. То есть посмотрите на это с strace -p [PID].

Возможно, вам также следует подумать о том, можете ли вы удалить HTTP-вызов из вашего использования API. Можете ли вы сохранить вещи в рамках одного и того же процесса Apache, сделав прямой вызов соответствующего кода, который обрабатывает запрос API?

Вероятно, важно рассказать людям, как вы используете PHP (например, mod_php, fpm и т. Д.). Это может быть частью понимания механизма блокировки кода.

mc0e
источник
Это может помочь с опросом внутренних элементов
ProfVersaggi
В качестве эксперимента я отключил вызовы API из цикла CURL и провел несколько тестов. Это изолировало проблему, так как во время этих тестов Apache2 deamon оставался здоровым.
ProfVersaggi