1

我正在使用 Webhostingpad 托管一个网站,但遇到了问题。当我的主页加载时,我目前正在对返回用于主页的内容的 php 脚本进行 8 次并发 ajax 调用。8 个 ajax 调用正在调用一个名为 run.php 的文件。该文件的工作只是从名为 amazon 的类中调用一个函数,该类在另一个名为 amazon.php 的文件中定义。

这是通过 ajax 调用 8 次的 URL。8 个调用之间的唯一区别是查询字符串:

http://my-domain.com/run.php?f=getItemsById&arg=id:B0043OYFKU,B001JKTTVQ,B004Y9D90Q,B003S516XO,B002XQ1YTK,B003V265QW,B00121UVU0,B004EDYQUE,B000P22TIY,B000E7WHLY

如您所见,我在 url 的“f”参数中传递函数名称。

run.php 文件如下所示:

require_once('amazon.php');

$function_name = $_REQUEST['f'];
$arg_parameter = $_REQUEST['arg'];

$arg_tmp = explode(";", $arg_parameter);
$arg_array = array();
foreach($arg_tmp as $key_value_pair){
    $exploded = explode(':', $key_value_pair);
    $key = $exploded[0];
    $value = $exploded[1];
    $arg_array[$key] = $value;
}

$amazon = new amazon();
echo $amazon->$function_name($arg_array);

如您所见,该文件只是从 amazon.php 调用一个函数并回显结果,因此我可以在 ajax 函数的回调中使用它。

以下是 amazon.php 中有关该getItemsById()功能的相关代码:

class amazon {

    private $url;
    private $accessKey = 'AKIAISJ2OHTBA888311SD';
    private $secretAccessKey = 'RM8EG61w3dLwjymtAEVdfsdiesd883711lskdf';

    function __construct(){
        $this->url = 'http://webservices.amazon.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=' . $this->accessKey . '&AssociateTag=global-18&Version=2011-08-01';
    }

    public function getItemsById($args = array()){

        $itemIds = $args['id'];

        $url = $this->url;
        $url .= '&Operation=ItemLookup';
        $url .= '&ItemId=' . $itemIds;
        $url .= '&ResponseGroup=Images,Small,Offers,VariationSummary,EditorialReview';

        $signedUrl = $this->amazonSign($url, $this->secretAccessKey);
        $returned_xml = file_get_contents($signedUrl);
        return $returned_xml;

    }
}

正如您在上面看到的,此函数正在调用 amazon.com 的 API 的 URL,并使用 PHP 的file_get_contents()函数返回 XML。我的问题是对 run.php 进行的一些 ajax 调用已成功执行,而另一些则得到 HTTP 500 内部服务器错误。当我在本地服务器上运行它时,它工作正常。当我在办公室的开发服务器上运行它时,它运行良好。但是,我一直在我的 Webhostingpad 服务器上看到这个问题。一些 ajax 调用返回 HTTP 500 错误。

我已经与 Webhostingpad 支持人员交谈过,他们提供给我的唯一见解是我超出了我的 CPU/内存资源限制。服务器的错误日志似乎证实了这一点:

[2013 年 2 月 19 日星期二 21:36:39] [错误] [客户端 68.174.126.115] (12) 无法分配内存:无法为 /home/my-server/ 创建子进程:/opt/suphp/sbin/suphp public_html/my-domain.com/run.php,引用者:http: //my-domain.com/

我对社区的问题是,这里是否有明显的记忆密集型?我觉得我正在做的事情并没有那么出格,所以我试图弄清楚我是否应该专注于优化我的脚本,或者我是否应该只是寻找另一个托管服务提供商。

4

1 回答 1

0

如果不能选择同步执行 AJAX 请求,您仍然可以对 PHP 脚本的内存消耗做一些事情。目前,PHP 脚本在将亚马逊返回的整个 XML 回显到客户端之前,会将其存储在内存中。如果 XML 很大并且您同时执行 8 次,那么内存不足并不奇怪。

一种解决方案是使用 cURL 向亚马逊发出请求,并使用 cURL 选项 CURLOPT_WRITEFUNCTION 将结果回显给客户端。这样,您可以使 amazon.php 脚本将结果 XML 流式传输到客户端,并且它不会使用太多内存。

示例 amazon.php 代码:

<?
function writeCallback($handle, $data)
{
    echo $data;    
    ob_flush();
    flush();
    return strlen($data);
}

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'http://webservices.amazon.com/onca/xml');
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'writeCallback');

ob_start(); // start output buffer
curl_exec($ch); // commence streaming
于 2013-02-20T07:39:33.123 回答