定时任务Crontab

0、基本概念 & 实现原理

 定时任务基本概念:

  • 调度器:负责管理Quartz应用运行时环境,用于调度定时任务。
  • 定时任务:按照某种时间规则,被调度的任务。

  a、从有无状态来说,有以下两种:

    有状态任务:每次执行的任务是同一个实例,不能被并行执行;如果该任务的执行时间超过下次触发的时刻,那么下次的触发将不会有作用。比如,一个有状态任务执行时间是5分钟,它的间隔时间是3分钟;如果正在执行的时候,下次触发时刻到达,则不会被执行。

    无状态任务:每次执行任务都是一个新的实例,可以并行执行。

  b、从执行的任务类型来说,有以下三种:

    SCA服务任务:任务是一个SCA服务。

    逻辑流任务:任务是一个逻辑流。

    任意方法任务:任务是一个方法。

  c、触发模式(触发器):用于定义任务调度的时间规则,主要有下面两种:

    固定时刻触发(简单触发器):一般用于实现间隔固定的时间执行任务,以及重复多少次,如每 2 小时执行一次,重复执行 5 次。

    日历周期触发(复杂触发器):使用Unix 'cron-like'表达式来定义时间规则,即利用一个包含 7 个字段的表达式来表示时间调度方式。例如,"0 15 10 * * ? *" 表示每天的 10:15AM 执行任务。对于涉及到星期和月份的调度比较合适。

  d、错失触发:定时任务如果错过触发而没有执行,比如系统停止;系统重启后,就会针对错失触发的定时任务进行处理,一般有两种错失触发策略(EOS_QRTZ_TRIGGERS表的MISFIRE_INSTR字段):

    立即重新触发:默认策略,立即执行一次定时任务,而不管错过几次。MISFIRE_INSTR字段值为1。

    错过触发:下次触发时间到来,再触发执行定时任务。MISFIRE_INSTR字段值为2。

  定时任务配置界面如下:

             

定时任务的实现:

  • 单机模式:调度器启动一个调度线程,根据触发器进行轮询,如果触发时刻到达,分配一个执行线程,执行定时任务。其中调度器及其状态、触发器及其状态、定时任务及其状态信息都会持久化到数据库中,所以系统停止,不会丢失定时任务;系统重新启动,会重新定时触发。
  • 集群模式:定时任务的集群,有负载均衡和故障切换的能力,可以给调度器带来高可用性和伸缩性。集群管理的实现是,集群上的每一个节点通过共享同一个数据库来工作的(Quartz通过启动两个维护线程来维护数据库状态实现集群管理,一个是检测节点状态线程,一个是恢复任务线程),通过数据库锁来实现并发控制(如果不是集群,使用内存锁进行并发控制)。负载均衡是自动完成的,集群的每个节点会尽快触发任务。当一个触发器的触发时间到达时,第一个节点将会获得任务,并改变任务状态,成为执行任务的节点。故障切换的发生是在当一个节点正在执行一个或者多个任务失败的时候。当一个节点失败了,其他的节点会检测到并且标识在失败节点上正在进行的数据库中的任务。任何被标记为可恢复的任务都会被其他的节点重新执行。没有标记可恢复的任务只会被释放出来,将会在下次相关触发器触发时执行。

  注:  如果是集群模式,则要求每个节点的时钟一定要一致,否则将发生无法预料的问题。建议简单触发器的间隔时间不要小于20秒。

Cron 是一个linux下的定时执行工具,也是Linux的内置服务,可以在不用人工干预的情况下运行作业

/sbin/service crond start   # 启动服务

/sbin/service crond stop   # 关闭服务

/sbin/service crond restart     # 重启服务

/sbin/service crond reload  # 重新载入配置 

/etc/rc.d/rc.local 这个脚本的末尾加上:  /sbin/service crond start    那么Cron这个服务就已经在进程里面了,我们就可以用这个服务了。

Cron提供的接口:

使用crontab命令编辑, cron服务提供crontab命令来设定cron服务的,参数说明:
  crontab -u   # 设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数

  crontab -l   # 列出某个用户cron服务的详细内容

  crontab -r   # 删除每个用户的cron服务

  crontab -e   # 编辑某个用户的cron服务   

  root查看自己的cron设置:  crontab -u root -l

  root删除fredcron设置:  crontab -u fred -r

  编辑cron服务的格式和约定: crontab -u root -e

  进入vi编辑模式:      */1 * * * * ls >> /tmp/ls.txt

crontab命令选项:
  -u  指定一个用户,

  -l  列出某个用户的任务计划,

  -r  删除某个用户的任务,

  -e  编辑某个用户的任务

任务调度的crond常驻命令:crond linux用来定期执行程序的命令。操作系统安装完成之后,默认会启动此任务的调度命令crond命令每分锺会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。

Linux任务调度的工作主要分为以下两类:

  • 系统执行的工作:系统周期性所要执行的工作,如备份系统数据、清理缓存
  • 个人执行的工作:某个用户定期要做的工作,例如每隔10分钟检查邮件服务器是否有新信,这些工作可由每个用户自行设置。

cron服务每分钟不仅要读一次 /var/spool/cron 内的所有文件,还需要读一次 /etc/crontab ,因此我们配置这个文件也能运用cron服务做一些事情。用crontab配置是针对某个用户的,而编辑 /etc/crontab 是针对系统的任务。

原理解析

Cron服务是由 守护进程crond和一组crontab文件 组成crond守护进程是在系统启动时由init进程启动的,受init进程的监视,如果它不存在了,会被init进程重新启动。这个守护进程每分钟唤醒一次,并通过检查crontab文件(任务表)判断需要执行什么任务每个用户有一个以用户名命名的crontab文件,存放在 /var/spool/cron/crontabs 目录里。若管理员允许或者禁止其他用户拥有crontab文件,则应编辑 /etc/cron.deny etc/cron.allow 这两个文件来禁止或允许用户拥有自己的 crontab文件(每一个用户都可以有自己的crontab文件,但在一个较大的系统中,系统管理员一般会禁止这些文件,而只在整个系统保留一个这样的文件)

crontab实际上是启动服务后读取所有配置文件,然后睡眠一分钟之后运行下一个任务,crontab服务启动后,会检查 /var/spool/cron/tabs 下所有用户的定时任务,然后加载到内存的队列中,然后每分钟检查一下 crontab文件是否有改动。可以理解为cron服务有2个线程,一个是调度处理定时任务,一个后台线程,后台线程检查配置文件是否有变动,如果有变动,则发送信号到调度进程,调度进程再重新读取配置文件更新内存中的任务队列,同理,service cron stop 也是发信号到cron服务(本次确认cron服务半僵死就是因为无法响应了)导致调度线程不知道变动,没有更新内存中的队列。从 /var/log/messages 观察,依然是修改或删除之前的定时任务在运行。 因此,为了保险,在用户里 crontab -r 删除用户的定时任务后,建议重启一下crontab服务(service cron stop后记得service cron status 查看一下是否停止成功,如果没有 kill -9 再 service cron start),也就是清空一下当前定时任务的内存队列,让cron服务重新加载,更重要的是防止cron服务挂住没重新加载定时任务队列。

3.cron文件语法:

分 小时 日 月 星期 命令

0-59 0-23 1-31 1-12 0-6 command (取值范围,0表示周日一般一行对应一个任务)


4.记住几个特殊符号的含义:

"*"  代表取值范围内的数字,

"/"  代表"每",

"-"  代表从某个数字到某个数字,

","  分开几个离散的数字 一、任务调度设置文件的写法 可用crontab -e命令来编辑,编辑的是/var/spool/cron下对应用户的cron文件,也可以直接修改/etc/crontab文件 具体格式如下:

Minute Hour Day Month Dayofweek command

分钟 小时 天 月 天每星期 命令 每个字段代表的含义如下:

Minute 每个小时的第几分钟执行该任务

Hour 每天的第几个小时执行该任务

Day 每月的第几天执行该任务

Month 每年的第几个月执行该任务

DayOfWeek 每周的第几天执行该任务

Command 指定要执行的程序 在这些字段里,除了“Command”是每次都必须指定的字段以外,其它字段皆为可选字段,可视需要决定。对于不指定的字段,要用“*”来填补其位置。 举例如下:

5 * * * * ls 指定每小时的第5分钟执行一次ls命令

30 5 * * * ls 指定每天的 5:30 执行ls命令

30 7 8 * * ls 指定每月8号的7:30分执行ls命令

30 5 8 6 * ls 指定每年的6月8日5:30执行ls命令

30 6 * * 0 ls 指定每星期日的6:30执行ls命令[注:0表示星期天,1表示星期1,以此类推,也可以用英文来表示,sun表示星期天,mon表示星期一等。]

30 3 10,20 * * ls 每月10号及20号的3:30执行ls命令[注:“,”用来连接多个不连续的时段]

25 8-11 * * * ls 每天8-11点的第25分钟执行ls命令[注:“-”用来连接连续的时段]

*/15 * * * * ls 每15分钟执行一次ls命令 [即每个小时的第0 15 30 45 60分钟执行ls命令 ]

30 6 */10 * * ls 每个月中,每隔10天6:30执行一次ls命令[即每月的1、11、21、31日是的6:30执行一次ls命令。 ]

每天7:50以root 身份执行/etc/cron.daily目录中的所有可执行文件

50 7 * * * root run-parts /etc/cron.daily [ 注:run-parts参数表示,执行后面目录中的所有可执行文件。 ]



二、新增调度任务 新增调度任务可用两种方法:

1、在命令行输入: crontab -e 然后添加相应的任务,wq存盘退出。

2、直接编辑/etc/crontab 文件,即vi /etc/crontab,添加相应的任务。 三、查看调度任务



crontab -l //列出当前的所有调度任务

crontab -l -u jp //列出用户jp的所有调度任务 四、删除任务调度工作



crontab -r //删除所有任务调度工作 五、任务调度执行结果的转向 例1:每天5:30执行ls命令,并把结果输出到/jp/test文件中

30 5 * * * ls >/jp/test 2>&1

注:2>&1 表示执行结果及错误信息。 编辑/etc/crontab 文件配置cron

系统任务格式:

SHELL=/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin



MAILTO=root //如果出现错误,或者有数据输出,数据作为邮件发给这个帐号 HOME=/ //使用者运行的路径,这里是根目录

# run-parts

01 * * * * root run-parts /etc/cron.hourly

//每小时执行/etc/cron.hourly内的脚本

02 4 * * * root run-parts /etc/cron.daily

//每天执行/etc/cron.daily内的脚本

22 4 * * 0 root run-parts /etc/cron.weekly

//每星期执行/etc/cron.weekly内的脚本

42 4 1 * * root run-parts /etc/cron.monthly

//每月去执行/etc/cron.monthly内的脚本   

大家注意"run-parts"这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是文件夹名了

例如:

1、在命令行输入: crontab -e 然后添加相应的任务,wq存盘退出。

2、直接编辑/etc/crontab 文件,即vi /etc/crontab,添加相应的任务

11 2 21 10 * rm -rf /mnt/fb

一、相关配置

  • /var/spool/cron/   用于存放每个用户包括root的crontab任务,每个任务以创建者的名字命名
  • /etc/crontab   此文件负责调度各种管理和维护任务。
  • /etc/cron.d/      用于存放任何要执行的crontab文件或脚本。
  • /etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly、/etc/cron.monthly     用于存放脚本,可让它每小时/天/星期、月执行一次。

二、常用命令:

crontab [-u username]    // 省略用户表表示操作当前用户的crontab
    -e      (编辑工作表)
    -l      (列出工作表里的命令)
    -r      (删除工作)

crontab -e 进入当前用户的工作表编辑,crontab的命令构成为‘时间+动作’,其时间有分、时、日、月、周五种,操作符有:
  • * 取值范围内的所有数字
  • / 每过多少个数字
  • - 从X到Z
  • 散列数字

三、crontab时间说明

# .---------------- minute (0 - 59) 
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ... 
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)  OR
# |  |  |  |  |
# |  |  |  |  |
# *  *  *  *  *  command to be executed

minute:代表一小时内的第几分,范围 0-59。
hour:代表一天中的第几小时,范围 0-23。
mday:代表一个月中的第几天,范围 1-31。
month:代表一年中第几个月,范围 1-12。
wday:代表星期几,范围 0-7 (0及7都是星期天)。
who:要使用什么身份执行该指令,当您使用 crontab -e 时,不必加此字段。
command:所要执行的指令。
 

四、crontab服务状态

sudo service crond start     # 启动服务
sudo service crond stop      # 关闭服务
sudo service crond restart   # 重启服务
sudo service crond reload    # 重新载入配置
sudo service crond status    # 查看服务状态

五、crontab命令

crontab $filepath    # 重新指定crontab定时任务列表文件

crontab -l              # 查看crontab定时任务
    
crontab -e             # 编辑定时任务【删除-添加-修改】

# 添加定时任务
Step-One : 编辑任务脚本【分目录存放】【ex: backup.sh】
Step-Two : 编辑定时文件【命名规则:backup.cron】
Step-Three : crontab命令添加到系统crontab backup.cron
Step-Four : 查看crontab列表 crontab -l

 

六、实例

# 实例1:每1分钟执行一次myCommand
* * * * * myCommand

# 实例2:每小时的第3和第15分钟执行
3,15 * * * * myCommand

# 实例3:在上午8点到11点的第3和第15分钟执行
3,15 8-11 * * * myCommand

# 实例4:每隔两天的上午8点到11点的第3和第15分钟执行
3,15 8-11 */2  *  * myCommand

# 实例5:每周一上午8点到11点的第3和第15分钟执行
3,15 8-11 * * 1 myCommand

# 实例6:每晚的21:30重启smb
30 21 * * * /etc/init.d/smb restart

# 实例7:每月1、10、22日的4 : 45重启smb
45 4 1,10,22 * * /etc/init.d/smb restart

# 实例8:每周六、周日的1 : 10重启smb
10 1 * * 6,0 /etc/init.d/smb restart

# 实例9:每天18 : 00至23 : 00之间每隔30分钟重启smb
0,30 18-23 * * * /etc/init.d/smb restart

# 实例10:每星期六的晚上11 : 00 pm重启smb
0 23 * * 6 /etc/init.d/smb restart

# 实例11:每一小时重启smb
* */1 * * * /etc/init.d/smb restart

# 实例12:晚上11点到早上7点之间,每隔一小时重启smb
* 23-7/1 * * * /etc/init.d/smb restart


# 每天早上6点 
0 6 * * * echo "Good morning." >> /tmp/test.txt //注意单纯echo,从屏幕上看不到任何输出,因为cron把任何输出都email到root的信箱了。

# 每两个小时 
0 */2 * * * echo "Have a break now." >> /tmp/test.txt  

# 晚上11点到早上8点之间每两个小时和早上八点 
0 23-7/2,8 * * * echo "Have a good dream" >> /tmp/test.txt

# 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点 
0 11 4 * 1-3 command line

# 1月1日早上4点 
0 4 1 1 * command line SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root //如果出现错误,或者有数据输出,数据作为邮件发给这个帐号 HOME=/ 

# 每小时(第一分钟)执行/etc/cron.hourly内的脚本
01 * * * * root run-parts /etc/cron.hourly

# 每天(凌晨4:02)执行/etc/cron.daily内的脚本
02 4 * * * root run-parts /etc/cron.daily 

# 每星期(周日凌晨4:22)执行/etc/cron.weekly内的脚本
22 4 * * 0 root run-parts /etc/cron.weekly 

# 每月(1号凌晨4:42)去执行/etc/cron.monthly内的脚本 
42 4 1 * * root run-parts /etc/cron.monthly 

# 注意:  "run-parts"这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是文件夹名。   

# 每天的下午4点、5点、6点的5 min、15 min、25 min、35 min、45 min、55 min时执行命令。 
5,15,25,35,45,55 16,17,18 * * * command

# 每周一,三,五的下午3:00系统进入维护状态,重新启动系统。
00 15 * *1,3,5 shutdown -r +5

# 每小时的10分,40分执行用户目录下的innd/bbslin这个指令: 
10,40 * * * * innd/bbslink 

# 每小时的1分执行用户目录下的bin/account这个指令: 
1 * * * * bin/account

# 每天早晨三点二十分执行用户目录下如下所示的两个指令(每个指令以;分隔): 
203 * * * (/bin/rm -f expire.ls logins.bad;bin/expire$#@62;expire.1st) 

七、Django中的定时任务

# 添加定时任务到系统中
python manage.py crontab add

# 显示已经激活的定时任务
python manage.py crontab show

# 移除定时任务
python manage.py crontab remove
原文地址:https://www.cnblogs.com/hsmwlyl/p/10661855.html