您的位置:首页 > 编程语言 > PHP开发

PHP使用Yii框架写一个不间断执行的脚本

2013-07-17 16:57 381 查看

工作脚本:通过从Redis队列中读取数据去一个远程地址查询订单是否完成,如果完成,进行下一步操作并且把此订单从队列中删除,如果订单还未完成,则重新把订单放到队列尾部。因为Redis中队列的数据是动态的,因此此脚本要不间断的工作。

异常退出监控:通过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文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息