异常退出监控:通过Linux的定时任务调用脚本,工作脚本在工作的时候会锁定一个创建的pid文件,因为脚本一直工作,所以pid文件一直是锁定状态,如果Pid文件是锁定的,就表示已经有一个工作脚本再运行了,退出本次脚本执行;如果pid文件未锁定,就表示脚本异常退出了,则再次启用脚本。
代码如下:
<?php
//CConsoleCommand为Yii框架自带的类库,此脚本要放在Yii框架项目的protected/commands目录里面。
class CheckOrderCommand extends CConsoleCommand{
private $pidfile="/var/run/mp_checkorder.pid";//PID文件
private $filestream;//PID文件流
public function actionIndex(){
set_time_limit(0);
error_reporting(0);
$redis=Yii::app()->queue_redis;
$mobilepaylog=new MobilePayLog();
if(!$this->createPidFile()) exit;//如果PID文件已经被锁定,退出执行。
while(true){
if(!$redis->lsize('mp_entrance_orders')){//如果队列不存在
usleep(1000);
continue;
}
$_order=$redis->blpop('mp_entrance_orders');
$_order=$_order[1];
$order=json_decode($_order,true);
$url="http://testmp.uuzu.com/v2/Entrance/checkorder/";
$query=http_build_query($order);
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_TIMEOUT,0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$query);
$res=json_decode(curl_exec($ch),true);
curl_close($ch);
if($res['status']==101){//充值中。。。
$redis->rpush('mp_entrance_orders',$res);
usleep(1000);
continue;
}else if($res['status']==100){//充值完毕
//充值
$result=$mobilepaylog->mobileCharge($order['order_id'],$order['order_id'],$order['game_id'],$order['server_id'],$order['u_money'],$order['game_money'],$order['account'],$order['op_id']);
if(!$result){//充值失败
$redis->rpush('mp_entrance_orders',$_order);
echo date('Y-m-d H:i:s')." ".$order['order_id']." charge failed!\r\n";
usleep(1000);
continue;
}
echo date('Y-m-d H:i:s')." ".$order['order_id']." charge success!\r\n";
}else{//其他情况,丢弃
//输出写入日志
echo "error_message:".var_export($res,true);
usleep(1000);
continue;
}
}
}
//创建pid文件并锁定文件,失败返回false
private function createPidFile(){
if(is_file($this->pidfile)){
$this->filestream=fopen($this->pidfile, 'r+');
}else{
$this->filestream=fopen($this->pidfile, 'w');
}
if(!$this->filestream){
echo "open pid file failed\n";
return false;
}
if(!flock($this->filestream,LOCK_EX|LOCK_NB)){
echo "get lock failed\n";
return false;
}
if(fseek($this->filestream,0,SEEK_SET)==-1) {
echo "fseek file failed\n";
return false;
}
$pid = getmypid();
return fwrite($this->filestream,$pid);
}
}
此脚本是用Yii框架的方式写的,用Linux定时任务调用,命令crontab -e
然后添加: * * * * * /xxx/xxx/php /xxx/xxx/xxx/yiic CheckOrder index >> /tem/php/checkorder.log
上面的xxx路径根据自己系统路径更改,把脚本里面的输出写入到checkorder.log文件。