![使用 Internet Explorer 调用 PHP/CURL 来获取长时间运行的数据 API 会导致 Apache 2 服务器冻结并需要重新启动](https://linux22.com/image/638146/%E4%BD%BF%E7%94%A8%20Internet%20Explorer%20%E8%B0%83%E7%94%A8%20PHP%2FCURL%20%E6%9D%A5%E8%8E%B7%E5%8F%96%E9%95%BF%E6%97%B6%E9%97%B4%E8%BF%90%E8%A1%8C%E7%9A%84%E6%95%B0%E6%8D%AE%20API%20%E4%BC%9A%E5%AF%BC%E8%87%B4%20Apache%202%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%86%BB%E7%BB%93%E5%B9%B6%E9%9C%80%E8%A6%81%E9%87%8D%E6%96%B0%E5%90%AF%E5%8A%A8.png)
我正在运行一个 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 等)可能很重要。这可能是理解代码锁定机制的一部分。