crontab并发文件锁的使用

这是学习笔记的第 1907篇文章


  前几天在做任务时间调度的时候,写了一个Shell脚本,是通过脚本来操作corntab的配置,在修改之前会做备份,文件是crontab_bak_file,然后修改配置,生成文件crontab_bak_file_tmp。看起来是一个操作可控的脚本了。但是在执行批量的任务调度时,发现事情远比想象的复杂。 

本来是想crontab的修改频率不高,结果有一批实例是单机多实例,在调度的时候,可能在同一时间会有一批任务进来,会对同一台服务器的crontab产生并发的变更操作,结果上一次操作还没完,下一次操作的文件就会覆盖上一次的,最后导致变更结果不稳定,有一部分变更会被覆盖,从crontab -l的结果来看,是一些变更没有生效。

这里我们需要引入一种机制,即文件锁,这种操作其实和MySQL实例管理是类似的,如果存在一个lock文件,则不可以重复启停已存在的实例,属于保护机制,对于crontab的并发操作而言,这种情况是确实需要的。

Linux中本身有文件锁的支持,一般是和命令结合起来。这里不能原生调用,我们需要做一些转换。最后的实现可以举个通俗的例子,就好比一批人要通过一条河,只有一个独木桥,一次只能一人通过,那么我们就需要锁定一下,其他人只能等待,等待的时间周期是4秒钟,那么多个并发的执行时间可能是4秒钟,可能是10几秒钟。

部分代码参考如下,我对已有的逻辑也持续做了改进,保留了一些之前的代码,供参考。

cur_date=`date "+%Y%m%d_%H%M%S"`

crontab_bak_file="${bak_path}/crontab_${cur_date}.bak"

crontab_bak_file_tmp="${bak_path}/crontab_tmp_${cur_date}"


扫描二维码关注公众号,回复: 5485754 查看本文章

# 创建crontab任务函数

function create_crontab()

{

    #if [ -f ${crontab_bak_file_tmp} ]; then

    #    sleep 1;

    #else

        ${echo} > ${crontab_bak_file_tmp}

        ${crontab} -l > ${crontab_bak_file_tmp} 2>/dev/null

    #fi

     

    lock_flag=`flock -x ${crontab_bak_file_tmp} -c  "sleep 2;echo 1"`

    # echo $a

    if [ $lock_flag == '1' ];then

    task_command=$task_command" 2>&1 & ""#${task_code}"

    #echo $task_command

    crontab_task="${minute} ${hour} * * * ${task_command}" 

    if [ -f ${crontab_bak_file} ]; then 

        echo 'ok';

    else

        ${crontab} -l > ${crontab_bak_file} 2>/dev/null

    fi



    # 要添加的crontab任务

    jobcontent=`${grep} -w "${task_code}" ${crontab_bak_file_tmp}`

    if [ ! -n "${jobcontent}" ];then

        #${sed} -i "/.*xtrabackup_innodb_full_v6/d" ${crontab_bak_file_tmp}  # 已存在任务时会被sed删除,防止重复添加

        ${echo} "${crontab_task}" >> ${crontab_bak_file_tmp}

        crontab ${crontab_bak_file_tmp}

        logEntry 'Job complete'

    else

        ${sed} -i "/.*${task_code}/d" ${crontab_bak_file_tmp}  # 已存在任务时会被sed删除,防止重复添加

        #${sed} -i "/.*xtrabackup_innodb_full_v6/d" ${crontab_bak_file_tmp}  # 已存在任务时会被sed删除,防止重复添加

        ${echo} "${crontab_task}" >> ${crontab_bak_file_tmp}

        crontab ${crontab_bak_file_tmp}

        logEntry 'Job complete'        

    fi 

    fi

}



可以看到初步的效果如下:

640?wx_fmt=png




相关链接:




640?


猜你喜欢

转载自blog.csdn.net/weixin_36250635/article/details/88097024
今日推荐