使用 Internet Explorer 调用 PHP/CURL 来获取长时间运行的数据 API 会导致 Apache 2 服务器冻结并需要重新启动

使用 Internet Explorer 调用 PHP/CURL 来获取长时间运行的数据 API 会导致 Apache 2 服务器冻结并需要重新启动

我正在运行一个 PHP 程序,只要它不被 Microsoft Internet Explorer 浏览器调用,它就能正常工作,之后它会生成以下进程,锁定 Apache 2 并要求重新启动 Web 服务器(在 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 的请求后挂起

更多研发: Internet Explorer 10(Windows 8)导致 Apache 崩溃

PHP 程序使用卷曲获取 25 个项目的列表,并针对每个项目执行 (GET) API 调用,将结果返回到外部服务器,以供进一步处理。这是一个经典的长期运行数据程序。

让我头疼的是,除了 Internet Explorer 之外,它在所有其他浏览器中都运行良好 - 这导致 Web 服务器出现故障。

我已经询问了列出的研发部门,然后实施了建议的修复,但我仍然得到相同可预测、可重现、有问题的服务器行为。

我需要弄清楚如何保护服务器在遇到 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

答案1

很久以前,我曾看到过 Apache 进程通过 HTTP 调用同一服务器上由 Apache 进程提供服务的另一个 URL 而导致 Apache 锁定的情况。有时,我会遇到一堆进程在等待此类调用,而没有可用的 Apache 进程来为它们提供服务的情况。在我的例子中,我在某些网页前面有一个转换层,但在您自己的网站上调用 API 也是一样的。

发起原始调用的浏览器的特性可能会使这种情况更容易发生。例如,保持活动状态、超时行为等,但从根本上来说这不是浏览器的错。

如果情况与我看到的类似,那么您需要查看 curl 的使用超时行为。您包含的代码表明您已经了解了这一点,但您可能需要更细致地了解请求中它到达的确切位置。使用以下方法查看可能会很有趣tcpdump(或 ngrep,Wireshark,或其他)。此外,当调用进程挂起时,最好知道正在进行哪个系统调用。也就是说,使用 查看它strace -p [PID]

您可能还应该考虑是否可以从 API 的使用中删除 HTTP 调用。您是否可以通过直接调用处理 API 请求的相应代码来将事情保留在同一个 Apache 进程中?

告诉人们您如何运行 PHP(例如 mod_php、fpm 等)可能很重要。这可能是理解代码锁定机制的一部分。

相关内容