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


10

我正在运行一个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。

关于这个问题有很多文章,但是我在实现其中任何一个方面都没有成功:

收到IE 10/11的请求后,Apache Server 2挂起

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

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

让我吃惊的是,它可以在除Internet Explorer之外的所有其他浏览器中正常运行-这会导致Web服务器出现异常。

我已经询问了列出的R&D,然后实施了建议的修复程序,但是我仍然得到相同的可预测,可再现,有问题的服务器行为。

我需要弄清楚如何保护服务器,使其免受恶意攻击,以及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
我认为您需要以某种方式记录来自IE和其他没有问题的其他浏览器的完整HTTP请求,以便我们进行比较并寻找差异。请查看此问题,了解如何实现。IE必须对HTTP请求进行某些处理(某些额外或缺少的标头等?),导致Apache对其进行不同的处理。要么是它处于较低级别(IP数据包),那我肯定不希望如此。
Stijn de Witt 2014年

我对它进行了赏金,希望可以帮助您解决您的问题。
Stijn de Witt

2
再想一想,您可能会将其作为错误报告给Apache ...因为确实没有办法将其解释为不是Apache错误。这也可能会帮助您获得一些经验丰富的Apache专家来研究该问题(并希望予以解决)。如果您要走那条路线,将您遇到问题的页面缩小到仍然有问题的最小情况,可能会有所帮助。无论如何,这本身可能是有帮助的。
Stijn de Witt 2014年

使用setopt设置curl的超时时间
user1050544

3
客户端对php脚本访问哪些URL有影响吗?当您发现服务器处于上述状态时,cURL请求是否仍在进行中?可能是IE在响应速度太慢时重试了请求吗?如果对您的Web服务器的每个HTTP请求都可以使它向后端发起另外25个HTTP请求,则升级速度可能很快。您可以将cURL获得的响应重用于多个客户端吗?
kasperd 2014年

Answers:


5

很久以前,我看到Apache锁定是由Apache进程通过HTTP调用同一服务器上的Apache进程提供服务的另一个URL导致的。有时,我会遇到一堆等待此类调用的进程,而没有可用的Apache进程来为其服务。就我而言,我在某些网页的前面有一个翻译层,但是在您自己的站点上调用API几乎是同一回事。

浏览器发出原始呼叫的特性可能会使这种情况发生的可能性更高。例如,保持活动,超时行为等,但从根本上讲,这并不是浏览器的错。

如果像我看到的那样,那么您想看看使用curl时的超时行为。您所包含的代码表明您已经了解了这一点,但是您可能需要更细致地了解请求到达的确切位置。用tcpdump(或ngrep,Wireshark或其他任何东西)查看它可能很有趣。另外,最好在调用进程挂起时知道正在进行什么系统调用。也就是说,使用来查看它strace -p [PID]

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

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


这可能帮助与PHP内部的审讯... versaggi.net/phptest.phtml
ProfVersaggi

作为一个实验,我确实禁用了CURL循环中的API调用,并进行了大量测试。隔离了问题,因为在那些测试中,Apache2守护进程保持健康。
ProfVersaggi 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.