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

我在我的网站上有一个基本的chatbox模块,它每隔3秒用Jquery Ajax调用更新聊天箱,再加上另一个用于发送新消息的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服务与以下configuration:

 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 

问题:
– 这是正常的,Apache的每个httpd进程使用多lessCPU?
– 我怎样才能解决这个问题?

 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更新function。 使用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(); } 

我以前有类似的问题,事实证明是与会话锁定。 当会话由启动会话的PHP脚本打开时,会话文件被锁定。 这意味着,如果您的网页向PHP脚本发出大量请求(例如,通过Ajax加载内容),则每个请求可能会锁定会话并阻止其他请求完成。 这在这里详细描述。

所以你需要做:

 session_write_close(); 

如果这不是原因检查,你没有做任何计算密集型的东西,大的SQL调用大量的递归等。