【转载】PHP使用1个crontab管理多个crontab任务

转载来自: http://www.cnblogs.com/showker/archive/2013/09/01/3294279.html

http://www.binarytides.com/php-manage-multiple-cronjobs-with-a-single-crontab-entry/

In many php applications there are multiple tasks that need to be run via cron at different times. In a typical application you may be doing the following tasks via cronjobs :

1. Backup database.
2. Send out email to subscribers.
3. Clear temporary files.
4. Fetch xml feeds from some source and store them in database.

So if you had separate php files doing these tasks , and had a cronjob entry for each , your cronjob could look like this :

MAILTO="[email protected]"
0 0 * * * /var/www/my_app/backup_database.php
12 2 * * * /var/www/my_app/email_to_subscribers.php
10 5 * * * /var/www/my_app/clear_temp_files.php
10 7 * * * /var/www/my_app/fetch_xml_feeds.php

The above is the simplest approach to manage multiple cronjobs for your php application. However this approach has many drawbacks :

1. Multiple entries in crontabs means more time and effort needed to edit the crontab and maintain it.

- Since this approach involves writing each task separately in the cron list , it becomes difficult to maintain.

2. The crontab command has to be used everytime a change is to be made.

- You need to either manually do a `crontab -t` in the shell prompt or make your php application do it , everytime there is a change in either the tasks or their timing.

3. If the script name changes then have to edit the crontab file again.
4. A log email would be generated for every cron run, creating multiple log emails.

- Every task that is running would generate a cronlog and email itself to the email specified

5. Inefficient when there are 10s or 100s of tasks to be run via cron.

- Do you think it is a good idea if you had many many tasks to do.

An alternative solution

How about having only 1 entry in the cronjobs, and that 1 cronjob manages the rest of the cronjobs.

1. Add only 1 task to the crontab rule say :

1 * * * * * php /path/to/cronjob.php

The cronjob.php file would run all the tasks that need to be run via cron. Its important to note that this cronjob.php will run every minute and forever. Do not be worried about it eating too much of system resources. It is a faily light thing and does not load your CPU or RAM with anything heavy.(注意这个cronjob.php会每分钟执行一次,而且一直会一直这样。不必担心这会消耗太多系统资源,这是一个非常轻量级的东西,它不会额外占用你的CPU和内存)

Now the next thing would be to make sure cronjob.php can run all the tasks at the right time.

2. Now we need to have different tasks have a different cron schedule. Lets say there are 3 different tasks to run at 3 different times :

0 5 * * * database_backup
0 5 1,15 * * monthly_sales_report
0 10 15 02 * purchase_report


The cronjob.php that runs every minute should have an array like this :

1 $cronjobs = array();
2
3 $cronjobs[‘database_backup‘] = ‘0 5 * * *‘;
4 $cronjobs[‘monthly_sales_report‘] = ‘0 5 1,15 * *‘;
5 $cronjobs[‘purchase_report‘] = ‘0 10 15 02 *‘;

Now we test each job/task for the timestamp and run it like this :

1 foreach($cronjobs as $method => $cron)
2 {
3     $time = time();
4         if( is_time_cron($time , $cron) )
5     {
6         $result = $method();
7         echo $result;
8     }
9 }

is_time_cron checks if the current timestamp matches the cron schedule or not. If it matches , then the task is executed. Theis_time_cron method can be found in the previous post here.

In this approach the benefits are :

1. Only 1 crontab entry.

The crontab list is clean and your application does not overload it.

2. Easy to maintain , does not need any modification unless the script path/name changes.

The crontab once created does not need any change unless the name or path of ‘cronjob.php‘ changes. Meanwhile the jobs inside cronjob.php can change their names , schedules and anything very easily.

3. To add/edit/remove tasks or change their time schedules only the cronjob.php needs to be changed.

This means easier modification , maintenance and the application can provide simple user interface to make changes anytime without the need to use crontab commands or anything as such.

The above mentioned approach can be applied to any language , not just php.

附加:判断当前时间蹉是否符合某个cronjob

http://www.binarytides.com/php-check-if-a-timestamp-matches-a-given-cron-schedule/

PHP check if a timestamp matches a given cron schedule

1 desktop:~$ php -a
2 Interactive shell
3
4 php > echo time();
5 1319362432
6 php > 

Above is an example of a given timestamp.

And a cron schedule can look like this 0 5 * * * - which means run everyday at 5 hours and 0 minutes.

Now in a php application you may need to test if a given timestamp , say 1319362432 matches a given cron schedule like 0 5 * * *.

Here is a quick php function that can do this task.

 1 /**
 2     Test if a timestamp matches a cron format or not
 3     //$cron = ‘5 0 * * *‘;
 4 */
 5 function is_time_cron($time , $cron)
 6 {
 7     $cron_parts = explode(‘ ‘ , $cron);
 8     if(count($cron_parts) != 5)
 9     {
10         return false;
11     }
12
13     list($min , $hour , $day , $mon , $week) = explode(‘ ‘ , $cron);
14
15     $to_check = array(‘min‘ => ‘i‘ , ‘hour‘ => ‘G‘ , ‘day‘ => ‘j‘ , ‘mon‘ => ‘n‘ , ‘week‘ => ‘w‘);
16
17     $ranges = array(
18         ‘min‘ => ‘0-59‘ ,
19         ‘hour‘ => ‘0-23‘ ,
20         ‘day‘ => ‘1-31‘ ,
21         ‘mon‘ => ‘1-12‘ ,
22         ‘week‘ => ‘0-6‘ ,
23     );
24
25     foreach($to_check as $part => $c)
26     {
27         $val = $$part;
28         $values = array();
29
30         /*
31             For patters like 0-23/2
32         */
33         if(strpos($val , ‘/‘) !== false)
34         {
35             //Get the range and step
36             list($range , $steps) = explode(‘/‘ , $val);
37
38             //Now get the start and stop
39             if($range == ‘*‘)
40             {
41                 $range = $ranges[$part];
42             }
43             list($start , $stop) = explode(‘-‘ , $range);
44
45             for($i = $start ; $i <= $stop ; $i = $i + $steps)
46             {
47                 $values[] = $i;
48             }
49         }
50         /*
51             For patters like :
52             2
53             2,5,8
54             2-23
55         */
56         else
57         {
58             $k = explode(‘,‘ , $val);
59
60             foreach($k as $v)
61             {
62                 if(strpos($v , ‘-‘) !== false)
63                 {
64                     list($start , $stop) = explode(‘-‘ , $v);
65
66                     for($i = $start ; $i <= $stop ; $i++)
67                     {
68                         $values[] = $i;
69                     }
70                 }
71                 else
72                 {
73                     $values[] = $v;
74                 }
75             }
76         }
77
78         if ( !in_array( date($c , $time) , $values ) and (strval($val) != ‘*‘) )
79         {
80             return false;
81         }
82     }
83
84     return true;
85 }
86
87 var_dump(time() , ‘0 5 * * *‘);  //true or false

How does it work

The above code uses the date format specifiers as follows :
‘min‘ => ‘i‘ ,
‘hour‘ => ‘G‘ ,
‘day‘ => ‘j‘ ,
‘mon‘ => ‘n‘ ,
‘week‘ => ‘w‘

over the timestamp to extract the minute , hour , day , month and week of a timestamp

Then it checks the cron format by splitting it into parts like 0 , 5 , * , * , * and then tests each part for the corresponding value from timestamp.

效果:

crontab命令:

1 * * * * * php /home/wwwroot/crontabs/cronjob.php

查看:

1 crontab -l

编辑:

1 crontab -e

参数:

 1     5       *       *       *     *     ls             指定每小时的第5分钟执行一次ls命令
 2     30     5       *        *     *     ls             指定每天的 5:30 执行ls命令
 3     30     7       8        *     *     ls             指定每月8号的7:30分执行ls命令
 4     30     5       8        6     *     ls             指定每年的6月8日5:30执行ls命令
 5     30     6       *        *     0     ls             指定每星期日的6:30执行ls命令[注:0表示星期天,1表示星期1, 以此类推,也可以用英文来表示,sun表示星期天,mon表示星期一等。]
 6     30     3     10,20      *     *     ls     每月10号及20号的3:30执行ls命令[注:“,”用来连接多个不连续的时段]
 7     25     8-11     *       *     *     ls       每天8-11点的第25分钟执行ls命令[注:“-”用来连接连续的时段]
 8     */15   *       *        *     *     ls         每15分钟执行一次ls命令 [即每个小时的第0 15 30 45 60分钟执行ls命令 ]
 9     30     6     */10       *     *     ls       每个月中,每隔10天6:30执行一次ls命令[即每月的1、11、21、31日是的6:30执行一次ls 命令。 ]
10     50     7       *        *     *     root     run-parts     /etc/cron.daily   每天7:50以root 身份执行/etc/cron.daily目录中的所有可执行文件[ 注:run-parts参数表示,执行后面目录中的所有可执行文件。 ]
 1 $time = date(‘YmdHi-s‘, time());
 2 $filename = $time . ‘.txt‘;
 3 //$fp = fopen("/home/wwwroot/crontabs/{$filename}", "w+"); //打开文件指针,创建文件
 4 //file_get_contents($fp,‘sssss‘);
 5 ######################################################################
 6 $cronjobs = array();
 7
 8 $cronjobs[‘database_backup‘] = ‘*/2 * * * *‘;
 9 $cronjobs[‘stttt‘] = ‘*/3 * * * *‘;
10 $cronjobs[‘monthly_sales_report‘] = ‘0 5 1,15 * *‘;
11 $cronjobs[‘purchase_report‘] = ‘0 10 15 02 *‘;
12
13
14
15
16
17 function database_backup(){
18     $r=  rand(200, 9000);
19     $fp = fopen("/home/wwwroot/crontabs/database_backup{$r}", "w+"); //打开文件指针,创建文件
20 }
21 function stttt(){
22     $r=  rand(200, 9000);
23     $fp = fopen("/home/wwwroot/crontabs/stttt{$r}", "w+"); //打开文件指针,创建文件
24 }

时间: 2024-10-16 17:34:03

【转载】PHP使用1个crontab管理多个crontab任务的相关文章

linux crontab -r 导致no crontab for root的原因及解决方案

使用方式 : crontab file [-u user]-用指定的文件替代目前的crontab. crontab-[-u user]-用标准输入替代目前的crontab. crontab-1[user]-列出用户目前的crontab. crontab-e[user]-编辑用户目前的crontab. crontab-d[user]-删除用户目前的crontab. crontab-c dir- 指定crontab的目录. crontab文件的格式:M H D m d cmd. crontab -r

[转载]对iOS开发中内存管理的一点总结与理解

对iOS开发中内存管理的一点总结与理解 做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作的理解是衡量一个程序员成熟与否的一个标准.好了,闲话不说,下面进入正题. 众所周知,ObjectiveC的内存管理引用的一种叫做“引用计数“ (Reference Count)的操作方式,简单的理解就是系统为每一个创建出来的对象,(这里要注意,只是对象,NSObject的子类,基本类型没有‘引用计数’)

[转载]DevOps建立全生命周期管理

全生命周期管理(ALM)领域作为企业DevOps实践的总体支撑,应该说是DevOps领域中最为重要的实践领域,也是所有其他实践的基础设施.现在很多企业都非常重视CI/CD自动化工具的引入和推广,但是对ALM的建设的重视程度并不够.CI/CD的火爆很大程度上是被Docker和DevOps的热潮带动的,但CI/CD自动化只是提升团队效率的一个环节,如果没有ALM工具的支撑,CI/CD也只是空中楼阁,无法起到整体优化团队工作效率的作用,甚至局部的效率提高还会造成团队的不适应甚至抵触.如果管理者看不到自

【转载】 Android源代码仓库及其管理工具Repo分析

软件工程由于需要不断迭代开发,因此要对源代码进行版本管理.Android源代码工程(AOSP)也不例外,它采用Git来进行版本管理. AOSP作为一个大型开放源代码工程,由许许多多子项目组成,因此不能简单地用Git进行管理,它在Git的基础上建立了一套自己的代码仓库,并且使用工 具Repo进行管理.工欲善其事,必先利其器.本文就对AOSP代码仓库及其管理工具repo进行分析,以便提高我们日常开发效率. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! 现代的

[转载]linux段页式内存管理技术

原始博客地址: http://blog.csdn.net/qq_26626709/article/details/52742470 一.概述 1.虚拟地址空间 内存是通过指针寻址的,因而CPU的字长决定了CPU所能管理的地址空间的大小,该地址空间就被称为虚拟地址空间,因此32位CPU的虚拟地址空间大小为4G,这和实际的物理内存数量无关.Linux内核将虚拟地址空间分成了两部分: 一部分是用户进程可用的,这部分地址是地址空间的低地址部分,从0到TASK_SIZE,称为用户空间 一部分是由内核保留使

crontab 及脚本添加crontab

crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数 crontab -l     列出某个用户cron服务的详细内容 crontab -r     删除没个用户的cron服务 crontab -e     编辑某个用户的cron服务 比如说root查看自己的cron设置:crontab -u root -l 再例如,root想删除fred的cron设置:crontab -u fred -r [[email protected] ~]#cronta

Linux定时任务Crontab使用 提示no crontab for root

crontab -e 输出如下 no crontab for f - using an empty one Select an editor. To change later, run 'select-editor'. 1. /bin/ed 2. /bin/nano <---- easiest 3. /usr/bin/vim.tiny Choose 1-3 [2]: 3 crontab: installing new crontab   然后就会打开一个文件,什么都不用做,直接保存,保存方式类似

[转载]开发人员需要熟知的常用Linux命令之二:Crontab

上面说了那么多的常用命令,还有一个功能我们也经常用到,就是定时器.日程表,一般通过crontab来运行:crontab 指定在固定时间或固定间隔执行特定的脚本:crontab的常用参数有如下3个: -e :执行文字编辑器来设定日程表,一般默认的编辑器是VI: -r :删除目前所有的日程表: -l :列出目前所有的日程表: 设置日程表时,需要有固定的格式,共6部分,各部分间用空格间隔:其中第6个部分是要执行的命令,前5个部分是设置执行时间或者时间间隔的,具体取值范围和意义如下: 分钟[0-59]

任务计划crontab、服务管理(chkconfig、systemd)

任务计划 crontab计划任务文件任务计划文件路径/var/spool/cron/ cat /etc/crontab [[email protected] ~]# cat /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # For details see man 4 crontabs # Example of job definition: # .---------------- minut