php + jquery ajax请求使用太多的CPU

时间:2012-06-22 15:59:18

标签: php linux performance apache

我的网站上有一个基本的聊天框模块,它使用Jquery Ajax调用每3秒更新一次聊天框,另外还有一个用于发送新消息的jquery调用。没有什么花哨。通常每个jquery ajax请求只需0.2秒。但是在连接20多人的服务器上,服务器CPU非常高,每个ajax请求开始需要12-14秒,这是不可接受的。而且每个httpd进程也消耗3% - 4%的CPU。

更新聊天室代码:

updatechatbox = $.getJSON("/chat/update",{ lastid: $("#messageBox li:last-child").attr("id") }, function(json) {
    $.each(json, function(key, val) {
        var m = val['message'];
        var id = val['id'];
        var messagebox = $("#messageBox ul");
        messagebox.append("<li id="+id+"><span class='msg'>"+m+"</span></li>");

        var myDiv = $("#messageBox");
        myDiv.animate({ scrollTop: myDiv.prop("scrollHeight") - myDiv.height() }, 0);
    });
});

服务器是Fedora 15运行nginx作为代理和apache用于Web服务,具有以下配置:


Timeout 120
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15

IfModule prefork.c
  StartServers       8
  MinSpareServers    5
  MaxSpareServers   20
  ServerLimit      256
  MaxClients       256
  MaxRequestsPerChild  400
IfModule

IfModule worker.c
  StartServers         2
  MaxClients         150
  MinSpareThreads     25
  MaxSpareThreads     75
  ThreadsPerChild     25
  MaxRequestsPerChild  0
IfModule

问题:
  - 对于每个httpd进程,使用那么多CPU的apache是​​正常的吗?
 - 我怎样才能解决这个问题?

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
20089 apache    20   0 57524  16m 5840 S  7.3  0.8   0:18.16 httpd
19715 apache    20   0 56828  16m 5852 S  6.6  0.8   0:21.58 httpd
19749 apache    20   0 58536  16m 5864 S  6.6  0.8   0:22.29 httpd
19732 apache    20   0 62880  21m 5856 S  5.6  1.0   0:19.14 httpd
19803 apache    20   0 62076  21m 5840 S  5.3  1.1   0:17.94 httpd
19821 apache    20   0 61856  21m 5828 S  5.0  1.0   0:17.81 httpd
21574 apache    20   0 61584  18m 4664 S  3.3  0.9   0:00.69 httpd
19772 apache    20   0 61856  21m 5864 S  2.6  1.1   0:18.53 httpd
19932 apache    20   0 61856  20m 5844 S  2.6  1.0   0:17.07 httpd
14307 mysql     20   0  306m  52m 4576 S  2.3  2.6  81:32.57 mysqld
13175 nginx     20   0 15532 2284 1032 S  0.3  0.1   0:04.61 nginx

编辑:我的PHP更新功能。使用Zend Framework v1.11.11

public function updateAction()
{
    $auth = Zend_Auth::getInstance();
    $user_info = $auth->getStorage()->read();
    $adminsess = new Zend_Session_Namespace("admin");
    $referrer = $_SERVER['HTTP_REFERER'];

    $user_id = $user_info->id;

    $query = "SELECT m.id, m.message, m.user_id
              FROM messagebox m
              LEFT JOIN users u ON m.user_id = u.id";

    if(isset($_GET['lastid']) && $_GET['lastid'] != ""){
        $lastId = $_GET['lastid'];
        $query .= "WHERE m.id > $lastId";
    }

    $r = $db->query($query);
    $result = $r->fetchAll();

    $data = array();

    if(count($result) > 0) {
        foreach($result as $row) {
            $data[$row['id']]['id'] = $row['id'];
            $data[$row['id']]['message'] = $row['message'];
            $data[$row['id']]['user_id'] = $user_id;
        }
    }

    echo json_encode($data);
    $this->_helper->layout->disableLayout();
}

1 个答案:

答案 0 :(得分:2)

之前我遇到过类似的问题,原来是会话锁定。当启动会话的PHP脚本打开会话时,此会话文件将被锁定。这意味着如果您的网页向PHP脚本发出大量请求,例如,通过Ajax加载内容,则每个请求都可能锁定会话并阻止其他请求完成。详细描述了here

因此您需要这样做:

session_write_close();

如果这不是原因检查你没有做任何计算密集的事情,比如大SQL调用很多递归等。