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

Я запускаю программу 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 "**

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

Существует много статей, написанных о проблеме, но я не имел никакого успеха, реализовывая любой из них:

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

Больше R&D: Apache катастрофического отказа Internet Explorer 10 (Windows 8)

Программа PHP использует ЗАВИХРЕНИЕ, чтобы взять список 25 объектов и выполнить (ПОЛУЧИТЬ) вызов API каждого к внешнему серверу, который возвращает данные JSON для последующей обработки. Это - классическая длительная программа обработки данных.

То, что печет мою лапшу, - то, что она хорошо работает в любом браузере кроме Internet Explorer - который заставляет веб-сервер неправильно себя вести.

Я опросил перечисленного R&D и затем некоторых, реализовал предложенные исправления, все же я все еще получаю то же предсказуемое, recreatable, проблематичное поведение сервера.

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

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

Вот снимок моего ВИХРЕВОГО кода:

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

10
задан 25 October 2019 в 20:27
1 ответ

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

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

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

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

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

5
ответ дан 2 December 2019 в 22:13

Теги

Похожие вопросы