程序啟動(dòng)如下所示:
$ sudo php start.php start
Workerman start in DEBUG mode
----------------------- WORKERMAN -----------------------------
Workerman version:3.3.9 PHP version:5.3.3
------------------------ WORKERS -------------------------------
user worker listen processes status
root YourAppBusinessWorker none 1
root JDwuliu-YourAppGateway json://192.168.1.105:8185 1
root JDwuliu-HttpGateway http://192.168.1.105:8184 1
root Register text://192.168.1.105:1242 1
root JDwuliu-WebGateway websocket://192.168.1.105:8188 1
----------------------------------------------------------------
Press Ctrl-C to quit. Start success.
在成功啟動(dòng)幾個(gè)小時(shí)后,cpu會(huì)增長(zhǎng)到90%多,然后日志開始報(bào)錯(cuò):
2017-09-12 10:53:32 pid:72082 SendBufferToWorker fail. The connections between Gateway and BusinessWorker are not ready. See http://wiki.workerman.net/Error3 for detail,
導(dǎo)致JDwuliu-HttpGateway這個(gè)進(jìn)程不會(huì)接收數(shù)據(jù),但是JDwuliu-YourAppGateway和JDwuliu-WebGateway 。請(qǐng)問(wèn)這是什么原因呢???
pid memory listening worker_name connections total_request send_fail throw_exception
16758 4.25M none YourAppBusinessWorker 4 673 0 0
16759 2.75M json://192.168.1.105:8185 JDwuliu-YourAppGateway 2 1 0 0
16760 2.75M http://192.168.1.105:8184 JDwuliu-HttpGateway 2 3 0 0
16761 2.5M text://192.168.1.105:1242 Register 4 2440 0 0
16762 2.75M websocket://192.168.1.105:8188 JDwuliu-WebGateway 3 24930 0 0
pid為16758 這個(gè)進(jìn)程
安裝了libevent,也優(yōu)化了內(nèi)核參數(shù),但是cpu還是會(huì)蹦到90%,業(yè)務(wù)代碼如下(websocket協(xié)議)
//查詢所有車輛id
$cars_id = $db1->select('car_id')->from('carinfo')->query();
foreach($cars_id as $car_id)
{
$gps_data = $db1->select('gps_lon,gps_lat')->from($car_id.'_LOCATIONINFO')->orderByDESC(array('u_id'))->limit(1)->query();
$gps_data = $car_id;
//查詢車輛類型
$type = $db1->select('type')->from('carinfo')->where("car_id = '{$car_id}'")->query();
$gps_data = $type;
$ret = insert_lesson($query_data, "data", $gps_data);
}
//正在運(yùn)行中
$trans_car_data = $db1->query("select count(*) from carinfo where status = '0'");
//停止
$idle_car_data = $db1->query("select count(*) from carinfo where status = '1'");
//正在運(yùn)行中
$hitch_car_data = $db1->query("select count(*) from carinfo where hitch = '1'");
//車輛狀態(tài)統(tǒng)計(jì)
$car_status = array("trans_car" => $trans_car_data,
"hitch_car" => $hitch_car_data,
"idle_car" => $idle_car_data);
$all_cars_data = array("resData" => array
("result" => 0,
"msg" => "查詢成功",
"data" => $query_data,
"status" => $car_status));
Gateway::sendToClient($client_id, json_encode($all_cars_data));
$timer_id = Timer::add(3, function()use($client_id, $db1)
{.......}
做了個(gè)定時(shí)器定時(shí)器中的內(nèi)容就和上面的代碼一樣,目的就是每三秒發(fā)送實(shí)時(shí)車輛數(shù)據(jù)給web端。我通過(guò)explain查看了執(zhí)行計(jì)劃只有count(*)這個(gè)是全表掃描,而且整個(gè)表也就30行左右的數(shù)據(jù)。到底是哪占用了這么高的cpu呢?
是在onMessage的時(shí)候添加的。是一個(gè)websocket接口,我的目的前端創(chuàng)建了一個(gè)websocket,然后訪問(wèn)過(guò)這個(gè)接口,我就每三秒回一次最新的數(shù)據(jù)給web端,不需要它再次請(qǐng)求,它只要接收就好了。當(dāng)web頁(yè)面跳轉(zhuǎn)的時(shí)候,websocket就斷了。目標(biāo)是創(chuàng)建一次定時(shí)器,然后自動(dòng)銷毀。難道不是這樣嗎?
找到問(wèn)題了,按照你的方法用strace 命令跟蹤了一下pid,發(fā)現(xiàn)即使把web端頁(yè)面關(guān)了,之前加的定時(shí)器還在跑,所以做了如下修改
$_SESSION = Timer::add(2, function()use($client_id, $db1, $car_id, $redis1)
public static function onClose($client_id) {
if(isset($_SESSION))
{
Timer::del($_SESSION);
}
}
在斷開的時(shí)候把定時(shí)器給銷毀了。我原以為在websocket斷開的時(shí)候定時(shí)器會(huì)自動(dòng)銷毀,所以才導(dǎo)致了上面的問(wèn)題,謝謝@walkor 大神