学而实习之 不亦乐乎

Linux:flock 命令 - 实现 crontab 任务串行化

2022-04-23 23:14:35

一、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:   显示版本

二、实现 crontab 任务串行化

flock 命令最大的用途就是实现对 crontab 任务的串行化。在 crontab 任务中,有可能出现某个任务的执行时间超过了 crontab 中为此任务设定的执行周期,这就导致了当前的任务实例还未执行完成,crontab 又启动了同一任务的另外一个实例,这通常不是用户所期望的行为。极端情况下,如果某个任务执行异常一直未返回,crontab 不会处理这种情形,会继续启动新的实例,而新的实例很可能又会异常,这样就导致 crontab 对同一任务不断的启动新的实例,最终导致系统内存被耗尽,影响到整个操作系统的运行。

解决这个问题可以使用 flock 命令,通过对一个中间文件加文件锁来间接实现同一时刻某个任务只有一个实例运行。如下任务:

* * * * * flock -xn /tmp/test.lock -c '/home/xxx/yyy.sh >> ~/xxx.log 2>&1'

这里的定时任务是每分钟执行一次,但是任务中并未直接执行目标命令 '/home/xxx/yyy.sh >> ~/xxx.log 2>&1',而是将命令作为 flock 的 -c 选项的参数。flock 命令中,-x 表示对文件加上排他锁,-n 表示文件使用非阻塞模式,-c 选项指明加锁成功后要执行的命令。因而上面flock 命令的整体含义就是:如果对 /tmp/mytest.lock 文件(如果文件不存在, flock 命令会自动创建)加锁成功就执行后面的命令,否则不执行。

三、实例

30 0 * * * sleep 30;flock -xn /tmp/test.lock -c '/home/xxx/yyy.sh >> ~/xxx.log 2>&1'