crontab定时任务最佳实践
用crontab定时执行脚本时,可能存在没有设置环境变量的问题,也可能不是在脚本所在目录执行脚本,但写脚本引用文件时一般都用相对路径(相对于脚本所在目录)。
这些坑都可能导致正常的脚本在crontab环境下执行失败。
下面是一个提交crontab任务的脚本,可以自动设置环境变量和移动到脚本所在目录执行脚本:
#!/usr/bin/bash
# 此脚本帮助提交脚本任务,Usage: command.sh script.sh [arg1] [arg2] ...
# 注意单个参数不能有空格字符,否则会当做多个参数处理
#
# 此脚本会设置必要的环境变量,
# 然后移动到提交脚本的所在目录,以此作为当前目录执行脚本。
# chmod +x cur.sh
#
if [ "$1" = "" ]; then
echo 'Usage: command.sh script.sh [arg1] [arg2] ...' >&2
exit 1
fi
. /etc/profile
cur_file=$(basename $1)
params=""
i=0
for param in "$@"; do
if [ $i -gt 0 ]; then
params=$params" "$param
fi
let i++
done
cur_dir=$(dirname $1)
cd ${cur_dir}
script=`pwd`/${cur_file}
if [ ! "$params" = "" ]; then
script=$script" "$params
fi
echo -e "<=== $script ===> `date '+%Y-%m-%d %H:%M:%S'`\n" | tr -s " " >&2
{ time $script; }
提交crontab任务时需要用上面的脚本提交:
0 * * * * /path/cur.sh /path/script.sh >> /path/file.log 2>&1
任务脚本只需要专注于处理业务逻辑,举例:
#!/usr/bin/bash
# chmod +x script.sh
#
filename=`date '+%Y-%m-%d_%H:%M:%S'`
spark-submit --master yarn --deploy-mode cluster \
--class com.abc.Aclass \
--jars mysql-connector-java-5.1.46-bin.jar \
--num-executors 10 \
--executor-cores 10 \
--executor-memory 9G \
etl.jar \
> log/${filename}.log 2>&1
script.sh脚本文件的输出需要在crontab -e中重定向到文件。
此外cur.sh脚本还会输出脚本的名称、启动时间和执行耗时,打印到标准错误。