禅道管理系统的定时任务 代码
来源:互联网 发布:生命探测软件 编辑:程序博客网 时间:2024/06/16 18:05
禅道管理系统里面有一些定时任务的,例如更新燃尽图,定时备份数据库等。
昨天我发现禅道不能登录了,检查了一下发现禅道所在的目录没有空间了,排查了一下发现是禅道的定时任务每天备份数据库文件还有上传的附件,由于附件很大所以每天都占用大量的存储空间。
然后我删掉了那些多余的备份,另外想禁用掉禅道的自动备份。然后问题来了
禅道的定时任务是如何执行的呢?
首先想到的是crontab,因为禅道官网提供了一些脚本用来做这些操作的,它就生成了一些sh脚本,需要添加到cron里面,然后就可以定时执行了
问题是我检查了所有用的crontab,发现并没有禅道的任何定时任务项目。
这引起了我的好奇心,我决定追入禅道的代码看看究竟是什么原因使得禅道有了自动定时任务的功能
/** * Ajax exec cron. * * @access public * @return void */ public function ajaxExec() { ignore_user_abort(true); set_time_limit(0); session_write_close(); /* Check cron turnon. */ if(empty($this->config->global->cron)) die(); /* make cron status to running. */ $configID = $this->cron->getConfigID(); $configID = $this->cron->markCronStatus('running', $configID); /* Get and parse crons. */ $crons = $this->cron->getCrons('nostop'); $parsedCrons = $this->cron->parseCron($crons); /* Update last time. */ $this->cron->changeStatus(key($parsedCrons), 'normal', true); $this->loadModel('common'); $startedTime = time(); while(true) { /* When cron is null then die. */ if(empty($crons)) break; if(empty($parsedCrons)) break; if(!$this->cron->getTurnon()) break; /* Run crons. */ $now = new datetime('now'); $this->common->loadConfigFromDB(); foreach($parsedCrons as $id => $cron) { $cronInfo = $this->cron->getById($id); /* Skip empty and stop cron.*/ if(empty($cronInfo) or $cronInfo->status == 'stop') continue; /* Skip cron that status is running and run time is less than max. */ if($cronInfo->status == 'running' and (time() - strtotime($cronInfo->lastTime)) < $this->config->cron->maxRunTime) continue; /* Skip cron that last time is more than this cron time. */ if($cronInfo->lastTime > $cron['time']->format(DT_DATETIME1)) die(); if($now > $cron['time']) { $this->cron->changeStatus($id, 'running'); $parsedCrons[$id]['time'] = $cron['cron']->getNextRunDate(); /* Execution command. */ $output = ''; $return = ''; if($cron['command']) { if(isset($crons[$id]) and $crons[$id]->type == 'zentao') { parse_str($cron['command'], $params); if(isset($params['moduleName']) and isset($params['methodName'])) { $this->app->loadConfig($params['moduleName']); $output = $this->fetch($params['moduleName'], $params['methodName']); } } elseif(isset($crons[$id]) and $crons[$id]->type == 'system') { exec($cron['command'], $output, $return); if($output) $output = join("\n", $output); } /* Save log. */ $log = ''; $time = $now->format('G:i:s'); $log = "$time task " . $id . " executed,\ncommand: $cron[command].\nreturn : $return.\noutput : $output\n"; $this->cron->logCron($log); unset($log); } /* Revert cron status. */ $this->cron->changeStatus($id, 'normal'); } } /* Check whether the task change. */ $newCrons = $this->cron->getCrons('nostop'); $changed = $this->cron->checkChange(); if(count($newCrons) != count($crons) or $changed) { $crons = $newCrons; $parsedCrons = $this->cron->parseCron($newCrons); } /* Sleep some seconds. */ $sleepTime = 60 - ((time() - $now->getTimestamp()) % 60); //注意这里,sleep睡觉小于60秒 sleep($sleepTime); /* Break while. */ if(connection_status() != CONNECTION_NORMAL) break; if(((time() - $startedTime) / 3600 / 24) >= $this->config->cron->maxRunDays) break; } /* Revert cron status to stop. */ $this->cron->markCronStatus('stop', $configID); }
这是cron模块里面的一段代码,执行这段代码的时候服务端启动了一个死循环,来执行cron表里面的任务
执行到这段代码需要客户端发起一个http请求,他是通过这么来的
function startCron(){ $.ajax({type:"GET", timeout:100, url:createLink('cron', 'ajaxExec')});}这段代码是被footer.html.php文件里面的代码执行的
这段js代码是被浏览器执行的,但是因为已经有一个死循环在服务端执行了,如果这段代码被多次执行,完全是浪费服务器资源,禅道是如何避免多次执行的呢
if($this->loadModel('cron')->runable()) js::execute('startCron()');
还是刚才footer文件里面的代码,意思是如果cron模块是可运行的,才执行那个ajaxcron代码,继续看runable的代码
public function runable() { if(empty($this->config->global->cron)) return false; $lastTime = $this->getLastTime(); if($lastTime == '0000-00-00 00:00:00' or ((time() - strtotime($lastTime)) > $this->config->cron->maxRunTime)) return true; if(!isset($this->config->cron->run->status)) return true; if($this->config->cron->run->status == 'stop') return true; return false; }
$lastTime 是cron表里面lastTime最新时间的值(没错,这个表里面的时间一直被上面所说的循环update),上面的代码是如果cron表里面最新的时间离现在已经超过<pre name="code" class="php">maxRunTime(配置文件里面写的,是65秒),如果已经超过65秒了,那么认为是服务端那个死循环的php执行已经被停止了,就会自动在发起一个ajaxcron的请求。
禅道就是这么避免这个死循环被多次在执行的。也是通过这些代码来使得即使你没有配置系统的crontab,依然可以执行定时任务,这是个不错的思路。
0 0
- 禅道管理系统的定时任务 代码
- webcron 定时任务管理系统
- webcron 定时任务管理系统
- windows定时计划任务管理系统quartz.net的使用
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- 以代码的方式管理quartz定时任务的暂停、重启、删除、添加等
- 基于PHP的crontab定时任务管理
- linux基础(十四)定时任务和管理系统的临时文件
- Spring的定时任务的代码实例
- java定时任务管理
- Java 定时任务管理
- jobby 定时任务管理
- rex 管理定时任务
- quartz 定时任务管理
- java定时处理任务的代码
- yarn中的cgroup调度
- CSS:去除点击链接和按钮时出现的虚线框
- 温故知新(六):排序介绍
- 想在公司推广Golang吗-Golang之美
- C51单片机实现六位数码管时钟
- 禅道管理系统的定时任务 代码
- thinkphp跨库操作代码实例
- secondaryProgress无显示效果
- linux系统下修改文件夹目录权限
- HDFS HA支持多Standby节点机制
- 数组初始化
- jquery前台验证
- ueditor 图片在线管理显示不了
- Numpy 100题 —— Neophyte 初学者 10道题