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文件。
相关文章推荐
- 使用YII框架进行PHP程序的任务执行
- PHP计划任务:如何使用Linux的Crontab执行PHP脚本
- 详解PHP的Yii框架中自带的前端资源包的使用
- [我的PHP之旅] YII框架学习 03.连接数据库(使用ActiveRecord)
- javaweb 使用Process执行python脚本中的一个问题
- PHP的Yii框架中使用数据库的配置和SQL操作实例教程
- PHP计划任务:如何使用Linux的Crontab执行PHP脚本
- PHP计划任务:如何使用Linux的Crontab执行PHP脚本
- linux下使用cronjob定时执行php脚本
- 在PHP的Yii框架中使用行为Behaviors的方法
- 解决yii框架中,使用参数化查询时,IN只能查询一个的代替方法
- 如何使用Linux的Crontab执行PHP脚本
- windows下使用PHP实现定时执行脚本
- PHP的Yii框架使用中的一些错误解决方法与建议
- 使用 OAuth2-Server-php 在 Yii 框架上搭建 OAuth2 Server
- PHP 基于Yii框架中使用smarty模板的方法详解
- PHP计划任务:如何使用Linux的Crontab执行PHP脚本(转载)
- PHP计划任务:如何使用Linux的Crontab执行PHP脚本
- PHP的Yii框架中使用数据库的配置和SQL操作实例教程
- 使用register_shutdown_function实现php项目脚本执行失败的实时报警