欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

crontab

程序员文章站 2022-07-03 18:34:36
crontab 简介 ​ crontab常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。编辑好的crontab会被存放于“crontab”文件中,以供之后读取和执行。每个用户可以拥有自己的crontab文件。通常,crontab存储的指令被守护进程crond激活,crond常常 ......

crontab

简介

​ crontab常见于unix和类unix的操作系统之中,用于设置周期性被执行的指令。编辑好的crontab会被存放于“crontab”文件中,以供之后读取和执行。每个用户可以拥有自己的crontab文件。通常,crontab存储的指令被守护进程crond激活,crond常常在后台运行,每分钟检查是否有预定的作业需要执行。

命令选项

(1) crontab -e : 修改crontab文件。如果文件不存在会自动创建
(2) crontab -l : 显示crontab文件。
(3) crontab -r : 删除crontab文件。
(4) crontab -ir : 删除crontab文件前提醒用户

语法

{minute} {hour} {day-of-month} {month} {day-of-week} {full-path-to-shell-script}

minute: 区间为0-59
hour: 区间为0-23
day-of-month: 区间为0-31
month: 区间为1-12,1是1月,12是12月
day-of-week: 区间为0-7,周日可以是0或7

示例:

(1)在每天00:01运行,即每天凌晨过一分钟。

1 0 * * * /root/bin/hello.sh

(2)每个工作日(mon - fri)11:59pm运行

59 23 * * 1,2,3,4,5 /root/bin/hello.sh

(3)下面例子与上面的例子效果一样

59 23 * * 1-5 /root/bin/hello.sh

(4)每5分钟运行一次

*/5 * * * * /root/bin/hello.sh

(5)每个月的第一天1:10pm运行

10 13 1 * * /root/bin/hello.sh

(6)每个工作日11:00pm运行

0 23 * * 1-5 /root/bin/hello.sh

关于crontab每小时运行一次

正确写法:

*/60 * * * * /root/bin/hello.sh

以下均为错误写法:

0 * * * * /root/bin/hello.sh # 每小时的0分运行。虽然也是每小时运行一次,但是如果我是在10:20创建crontab,应该在11:20运行,而不是11:00
0 */1 * * * /root/bin/hello.sh # 和上面一样
* */1 * * * /root/bin/hello.sh # 更加错误的写法,分钟要求的是每分钟执行,而小时却要求每小时执行,最终以分钟为准。因此每分钟执行一次。

关于crontab每秒运行一次

​ 在简介中有提到过,crond守护进程每分钟检查一次是否有预定的作业需要执行,因此crontab没有办法直接做到每秒运行一次,最少每分钟运行一次。但是我们可以通过增加sleep语句来达到每秒执行的效果。

​ 以每30s执行一次为例:

* * * * * /root/bin/hello.sh
* * * * * sleep 30; /root/bin/hello.sh

​ 第二条crontab虽然与第一条同时被crond执行,但是需要延迟30s,通过延迟执行的方式达到了每30s执行一次的效果

​ 同理,每10s执行一次:

* * * * * /root/bin/hello.sh
* * * * * sleep 10; /root/bin/hello.sh
* * * * * sleep 20; /root/bin/hello.sh
* * * * * sleep 30; /root/bin/hello.sh
* * * * * sleep 40; /root/bin/hello.sh
* * * * * sleep 50; /root/bin/hello.sh

​ 如果要达到每秒执行一次,则需要添加60条crontab,这里就不赘述,留给大家自己思考叭(◕‿◕✿)

对于crontab任务堆积的处理

​ crontab在执行的过程中,可能由于任务执行错误或者在下一个任务开始前,前一个任务没有执行完成,导致大量的进程产生,最终可能导致死机等情况产生。

​ 之前做过一个告警外发的需求,要求实时的把最新告警给外发出去。这里我用的就是crontab,但是由于sql查询速度和网络延迟等情况,可能上一次的外发还没有执行完,下一次的外发就开始了,导致有些告警被重复外发。这里就可以使用flock来解决这个问题。

​ flock的本质是给某个crontab加锁,如果第二个进程发现这个crontab有锁,就会放弃执行。

flock命令选项

flock [-sxon][-w #] file [-c] command

-s, --shared:       获得一个共享锁
-x, --exclusive:    获得一个独占锁
-u, --unlock:       移除一个锁,通常是不需要的,脚本执行完会自动丢弃锁
-n, --nonblock:     如果没有立即获得锁,直接失败而不是等待
-w, --timeout:      如果没有立即获得锁,等待指定时间
-o, --close:        在与逆行命令前关闭文件的描述符号,用于如果命令产生子进程时会不受锁的管控
-c, --command       在shell中运行一个单独的命令
-h, --help          显示帮助
-v, --version       显示版本

任务举例:

# hello.lock为是一个锁临时文件
* * * * * flock -xn /root/bin/hello.lock -c '/root/bin/hello.sh'
* * * * * sleep 30; flock -xn /root/bin/hello.lock -c '/root/bin/hello.sh' 

好啦,关于crontab的使用方法就这些啦,如有补充,欢迎评论区留言(●'◡'●)