我的网站上有一个基本的聊天框模块,它使用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();
}
答案 0 :(得分:2)
之前我遇到过类似的问题,原来是会话锁定。当启动会话的PHP脚本打开会话时,此会话文件将被锁定。这意味着如果您的网页向PHP脚本发出大量请求,例如,通过Ajax加载内容,则每个请求都可能锁定会话并阻止其他请求完成。详细描述了here。
因此您需要这样做:
session_write_close();
如果这不是原因检查你没有做任何计算密集的事情,比如大SQL调用很多递归等。