crontab、flock、timeout的配合使用实现定时任务超时及报警

    技术2022-07-11  115

    需求场景

    开发后台的同学,经常需要写一些脚本定时启动运行,通常使用crontab来实现。有时候还有更加苛刻的需求:脚本不仅需要定时启动,而且还需要保证互斥 (同一时间只有一个进程在跑,上次的没结束则这次不启动)的要求,甚至还需要设置超时时间(当运行时间过长自动结束进程)和超时报警。那又该如何实现呢?答案是:crontab定时启动任务,flock保证互斥,timeout设置超时以及报警脚本

    crontab、flock、timeout的使用介绍

    crontab的使用

    crontab是Linux自带的实现定时任务程序,只能实现分钟级的定时任务。具体参考crontab 定时任务

    需要注意的点:

    实现每8分钟启动一次任务的实际执行情况是,从整点的0分钟开始每隔8分钟执行一次,所以56分钟时会执行一次且下次0分钟又会执行,其他小时、日应该也是类似。脚本的路径应该使用绝对路径或者使用cd命令到绝对路径

    flock的使用

    flock可以保证只有一个脚本单例执行。主要用的是互斥非阻塞模式,设置等待时间也有一定的用处,但我用的较少。

    参考使用flock命令确保脚本单例执行

    需要注意的点:

    flock的互斥文件最好使用绝对路径且以.lock结尾使用flock之后会生成相应的文件,后面命令完成结束之后并不会自动清除掉

    timeout的使用

    参考timeout(1)-Linux man page

    使用例子

    # 超时发送-9信号,超时执行后面的脚本输出failed timeout -s 9 5 sleep 20 || echo 'failed' # 未超时执行后面的脚本输出success timeout -s 9 10 sleep 5 && echo 'success' 复制代码

    需要注意的点

    timeout 正常结束的返回码是0timeout 超时kill结束的返回码是124

    配合使用例子

    首先定时执行的脚本task.sh如下:

    echo 'start at:' `date` # 大概3分钟 sleep 180 echo 'end at:' `date` 复制代码

    其次是超时报警通知脚本alarm.sh如下:

    # 追加输出超时时间到alarm.log echo 'timeout at:' `date` >>alarm.log # 其他的报警措施,发邮件、短信.... 复制代码

    由于上面的定时任务大概3分钟结束,所以我们的超时时间大于3分钟就行了(具体多少根据不同情况设置就行了),假设6分钟执行一次且互斥非阻塞,超时10分钟且超时执行报警脚本,则最终crontab文件如下

    */6 * * * * cd /data/projec && flock -xn ./task.lock -c 'timeout -9 600 sh task.sh || sh alarm.sh' 复制代码

    需要注意的点

    如果task.sh启动了子进程进行处理,则需要在task.sh的末尾加上wait命令等待全部子进程完成才结束,否则timeout无效

    cd /data/project nohub python3 main.py >main.log 2>&1 & wait 复制代码
    Processed: 0.010, SQL: 9