一、前言
在生产环境使用Linux Crontab配置数据库冷备脚本,结果今天登录上去一看,运行的时间不对,本应该在北京时间18点执行的脚本结果在10点钟就被执行了,而10点钟正是业务方使用系统最频繁的时候。
二、问题分析
crontab 配置如下
0 10 * * * sh bakdb.sh
因为系统时区设置是UTC标准,原本认为任务会在 UTC 10点(即北京时间18点整执行),然而实际执行的时间是UTC 2点(即北京时间10点钟执行,此时正是业务方使用系统的高峰期)。
具体原因:
我在阿里云国际站购买的澳洲区域的ECS实例,默认的时区竟然是北京时间(这里要吐槽一下阿里云),然后自己对系统时区进行调整,由北京时区调整为UTC,此时本应该重启crontab才会生效,但我以为crontab会自动识别到时区的变化,就没有重启,就造成执行时间不对的问题。
注:Ubuntu 用 service cron restart 重启,CentOS用service crond restart重启。
POS系统刚上线的时候定时任务也出过一次问题,也是数据库冷备并且没有做压缩,大约2G的数据量,机器时区是UTC,然后配置为0点钟执行,换算成北京时间就是8点钟,此时正是业务高峰,当时直接就把网络堵塞了,造成系统短暂Hold。
三、Crotab 表达式介绍
f1 f2 f3 f4 f5 program
- f1:分钟,f2小时,f3 一个月中第几天 ,f4 月份,f5 星期。
- f1为* 表示每分钟都要执行程序,f2为*表示每小时都要执行,其余依此类推。
- f1为a-b表示从第a分钟到第b分钟都要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,其余依此类推。
- f1为*/n表示每n分钟时间间隔都要执行一次,f2为*/n表示每n小时时间间隔都要执行一次,其余依此类推。
- 当 f1 为 a, b, c,... 时表示第 a, b, c,... 分钟要执行,f2 为 a, b, c,... 时表示第 a, b, c...个小时要执行,其余依此类推。
这个表达式理解一下就可以,自己写不出来也没太大关系,网上可以随找一个在线生成器&解释器,比如 https://www.bejson.com/othertools/cron/
另外 cron表达式,Spring、Quartz、Linux Crontab语法略有不同,这个需要注意一下。