工作调度
1. 工作调度种类
Linux 工作调度的种类: at, cron
- 一种是例行性的,就是每隔一定的周期要来办的事项;
- 一种是突发性的,就是这次做完以后就没有的那一种 ( 3C 大降价...)
2. 仅执行一次的工作调度
要使用单一工作调度时,我们的 Linux 系统上面必须要有负责这个调度的服务,那就是 atd 这 个玩意儿。
2.1. at命令
安装:
yum -y install at
或
apt-get install at
启动:
[root@study ~]# systemctl start atd # 启动atd服务
[root@study ~]# systemctl restart atd # 重新启动 atd 这个服务
[root@study ~]# systemctl enable atd # 让这个服务开机就自动启动
[root@study ~]# systemctl status atd # 查阅一下 atd 目前的状态
● atd.service - Job spooling tools
Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset: enabled) # 是否开机启动
Active: active (running) since Thu 2024-01-18 10:44:32 CST; 2s ago # 是否启动运行
Main PID: 3617529 (atd)
Tasks: 1 (limit: 23236)
Memory: 348.0K
CGroup: /system.slice/atd.service
└─3617529 /usr/sbin/atd -f
at [-mldv] TIME
-m :当 at 的工作完成后,即使没有输出讯息,亦以 email 通知使用者该工作已完成。
-l :at -l 相当于 atq,列出目前系统上面的所有该使用者的 at 调度;
-d :at -d 相当于 atrm ,可以取消一个在 at 调度中的工作;
-v :可以使用较明显的时间格式列出 at 调度中的工作列表;
-c :可以列出后面接的该项工作的实际指令内容。
TIME:时间格式,这里可以定义出“什么时候要进行 at 这项工作”的时间,格式有:
HH:MM 在今日的 HH:MM 时刻进行,若该时刻已超过,则明天的 HH:MM 进行此工作。
HH:MM YYYY-MM-DD 强制规定在某年某月的某一天的特殊时刻进行该工作!
HH:MM[am|pm] [Month] [Date] 也是一样,强制在某年某月某日的某时刻进行!
HH:MM[am|pm] + number 在某个时间点“再加几个时间后”才进行
2.2. at范例
2.2.1.再过五分钟后将user.db文件备份
[root@VM-24-3-centos test]# at now + 5 minutes
warning: commands will be executed using /bin/sh
at> cp user.db userBackup.db # ,可以输入多个指令
at> <EOT> #按ctrl+d结束输出
job 9 at Thu Jan 18 15:30:00 2024 # 任务编号9 执行时间 Thu Jan 18 15:30:00 2024
# 五分钟后就可以查看
[root@VM-24-3-centos test]# ls
user.db userBackup.db
2.2.2.将上述的第 9 项工作内容列出来查阅
#!/bin/sh
.... #忽略环境输出的一大堆环境变量
cp user.db userBackup.db # 这个就是我们执行的命令
··· # 忽略其他信息
2.2.3.由于今天23.50停电 我想要在今天23.40 保存任务并关机
at 23:40
warning: commands will be executed using /bin/sh
at> sync /test/xxxx
at> shutdown -h now
at> <EOT>
job 12 at Thu Jan 18 23:40:00 2024
2.3.at使用注意事项
2.3.1.发送邮件问题
要注意的是,如果在 at shell 内的指令并没有任何的讯息输出,那么 at 默认不会发 email 给执行者的。 如果你想要让 at 无论如何都发一封 email 告知你是否执行了指令,那么 可以使用“ at -m 时间格式 ”来下达指令喔! at 就会传送一个讯息给执行者,而不论该指令执行有无讯息输出了。
3. at 工作的管理
atq 查询本机任务列表
atrm (jobnumber)删除任务
3.1 范例
3.1.1.查询目前主机上面有多少的 at 工作调度?
[root@VM-24-3-centos test]# atq
12 Thu Jan 18 23:40:00 2024 a root
3.1.2.删除任务
atrm 12
4. 循环执行的例行性工作调度
相对于 at 是仅执行一次的工作,循环执行的例行性工作调度则是由 cron (crond) 这个系统 服务来控制的。刚刚谈过 Linux 系统上面原本就有非常多的例行性工作,因此这个系统服务 是默认启动的。另外, 由于使用者自己也可以进行例行性工作调度,所以啰, Linux 也提供 使用者控制例行性工作调度的指令 (crontab)。 下面我们分别来聊一聊啰.
4.1. 使用者设置
使用者想要创建循环型工作调度时,使用的是 crontab 这个指令啦~不过,为了安全性的问 题, 与 at 同样的,我们可以限制使用 crontab 的使用者帐号。
- /etc/cron.allow: 将可以使用 crontab 的帐号写入其中,若不在这个文件内的使用者则不可使用 crontab;
- /etc/cron.deny: 将不可以使用 crontab 的帐号写入其中,若未记录到这个文件当中的使用者,就可以使用 crontab 。
以优先顺序来说, /etc/cron.allow 比 /etc/cron.deny 要优先。
当使用者使用 crontab 这个指令来创建工作调度之后,该项工作就会被纪录到 /var/spool/cron/ 里面去了。举例来说dmtsai 使用 crontab 后, 他的工作会被纪录到 /var/spool/cron/dmtsai 里头去。
不要使用 vi 直接编辑该 文件, 因为可能由于输入语法错误,会导致无法执行 cron 。
cron 执行的每一项工作都会被纪录到 /var/log/cron 这个登录文件中,所以啰,如果你的Linux不知道有否被植入木马时,也可以搜寻一下/var/log/cron这个登录文件呢
4.2. 命令
Usage:
crontab [-u user] file
crontab [ -u user ] [ -i ] { -e | -l | -r }
-u :只有 root 才能进行这个任务,亦即帮其他使用者创建/移除 crontab 工作调度; -e :编辑 crontab 的工作内容
-l :查阅 crontab 的工作内容 (当前使用者的内容)
-r :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑。
4.2.1. 工作内容格式
分 时 日 月 周 指令
代表意义 | 分 | 时 | 日 | 月 | 周 | 指令 |
---|---|---|---|---|---|---|
代表意义 | 0-59 | 0-23 | 1-31 | 1-12 | 0-7 | 指令 |
- 周的数字为 0 或 7 时,都代表“星期天”的意思
辅助字符
辅助字符 | 代表意义 |
---|---|
* | 代表任何时刻都接受的意思!举例来说,范例一内那个日、月、周都是 * , 就 代表着“不论何月、何日的礼拜几的 12:00 都执行后续指令”的意思! |
, | 代表分隔时段的意思。举例来说,如果要下达的工作是 3:00 与 6:00 时,就会 是: > 0 3,6 *** command 时间参数还是有五栏,不过第二栏是 3,6 ,代表 3 与 6 都适用! |
- | 代表一段时间范围内,举例来说, 8 点到 12 点之间的每小时的 20 分都进行一 项工作: > 20 8-12 *** command 仔细看到第二栏变成 8-12 喔!代表 8,9,10,11,12 都适用的意思! |
/n | 那个 n 代表数字,亦即是“每隔 n 单位间隔”的意思,例如每五分钟进行一次, 则: > * /5 * *** command 很简单吧!用 * 与 /5 来搭配,也可以写成 0-59/5 ,相同意思! |
crontab 每个人都只有一个文件存在,就是在 /var/spool/cron 里面啊! 还有建议您:“指 令下达时,最好使用绝对路径,这样比较不会找不到可执行文件喔!
4.3 示例
4.3.1. 用 dmtsai 的身份在每天23点关机
[dmtsai@study ~]$ crontab -e
# 此时会进入 vi 的编辑画面让您编辑工作!注意到,每项工作都是一行。
0 12 * * * mail -s "at 12:00" dmtsai < /home/dmtsai/.bashrc
#分 时 日 月 周 ==============指令串========================
4.3.2.查询dmtsai用户的crontab任务
[dmtsai@study ~]crontab -l
0 12 * * * mail -s "at 12:00" dmtsai < /home/dmtsai/.bashrc
4.3.2.dmtsai用户移除发送邮件任务
# 若仅想要移除一项工作而已的话,必须要用 crontab -e 去编辑
# 移除所有
crontab -r
4.4. 系统的配置文件
/etc/crontab, /etc/cron.d/*
这个“ crontab -e ”是针对使用者的 cron 来设计的,如果是**“系统的例行性任务“是不需要crontab -e管理的**。你只要编辑 /etc/crontab 这个文件就可以。
crontab
crontab -e 这个 crontab 其实是 /usr/bin/crontab 这个可执行文件,但是 /etc/crontab 可是一个纯文本文件,你可以root 的身份编辑一下这个文件。
cron
cron 这个服务的最低侦测限制是“分钟”,所以“ cron 会每分钟去读取一次 /etc/crontab 与 /var/spool/cron 里面的数据内容 ”,因此,只要你编辑完 /etc/crontab 这个文 件,并且将他储存之后,那么 cron 的设置就自动的会来执行了
注:在 Linux 下面的 crontab 会自动的帮我们每分钟重新读取一次 /etc/crontab 的例行工作事 项,但是某些原因或者是其他的 Unix 系统中,由于 crontab 是读到内存当中的,所以在你修 改完 /etc/crontab 之后,可能并不会马上执行, 这个时候请重新启动 crond 这个服务 吧!“systemctl restart crond”
4.4.1. /etc/crontab
[root@VM-24-3-centos ~]$ cat /etc/crontab
SHELL=/bin/bash #使用哪种 shell 接口
PATH=/sbin:/bin:/usr/sbin:/usr/bin #可执行文件搜寻路径
MAILTO=root #若有额外STDOUT,以 email将数据送给谁
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
-
MAILTO=root
当 /etc/crontab 这个文件中的例行性工作的指令发生错误时,或者是该工作的 执行结果有 STDOUT/STDERR 时,会将错误讯息或者是屏幕显示的讯息传给谁.默认当然 是由系统直接寄发一封 mail 给 root .不过, 由于 root 并无法在用户端中以 POP3 之类的 软件收信,因此,可以改成自己的帐号。
-
PATH=....
输入可执行文件的搜寻路径 -
“分 时 日 月 周 身份 指令”七个字段的设置
这里分 时 日 月 周后面跟的是身份。用来指明用什么身份来执行命令。
-
crond 服务读取配置文件的位置
- /etc/crontab 跟系统的运行比较有关系
- /etc/cron.d/* 跟系统的运行比较有关系
- /var/spool/cron/* 跟用户自己的工作比较有关的配置文件
4.4.2 /etc/cron.d/* 说明
[Test@VM-24-3-centos ~]$ ls -l /etc/cron.d
total 12
-rw-r--r--. 1 root root 128 Jul 14 2022 0hourly
-rw------- 1 root root 110 Nov 21 14:58 sgagenttask
-rw------- 1 root root 229 Nov 21 15:56 yunjing
0hourly
[Test@VM-24-3-centos ~]$ cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly
内容跟 /etc/crontab 几乎一模一样!但实际上是有设置值.
如果你想要自己开发新的软件,该软件要拥有自己的 crontab 定时指令时,就可以将“分、 时、日、月、周、身份、指令”的配置文件放置到 /etc/cron.d/ 目录下! 在此目录下的文件 是“crontab 的配置文件脚本”
如果你想要自己开发新的软件,该软件要拥有自己的 crontab 定时指令时,就可以将“分、 时、日、月、周、身份、指令”的配置文件放置到 /etc/cron.d/ 目录下! 在此目录下的文件 是“crontab 的配置文件脚本
每个整点的一分会执行“ run-parts /etc/cron.hourly ”那什么是 run-parts 呢? 如果你有去分析一下这个可执行文件,会发现他就是 shell script,run-parts 脚本会在大约 5 分钟内随机选一个时间来执行 /etc/cron.hourly 目录内的所有可执行文件!因此,放在 /etc/cron.hourly/ 的文件,必须是能被 直接执行的指令脚本, 而不是分、时、日、月、周的设置值喔!注意注意!
在 /etc/ 下面其实还有 /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/,那三 个目录是代表每日、每周、每月各执行一次的意思吗。,跟 /etc/cron.hourly/ 不太一样的是,那三个目录是由 anacron 所执行的。
而 anacron 的 执行方式则是放在 /etc/cron.hourly/0anacron 里面耶~跟前几代 anacron 是单独的 service 不太一样
4.5. 配置文件总结
- /etc/cron.allow:将可以使用 crontab 的帐号写入其中,若不在这个文件内的使用者则不 可使用 crontab;
- /etc/cron.deny:将不可以使用 crontab 的帐号写入其中,若未记录到这个文件当中的使 用者,就可以使用 crontab。
- /var/spool/cron/[username]:[username]使用crontab创建的任务。注不要直接使用vi去编辑该文件,容易发生异常。
- /var/log/cron:cron 执行的每一项工 作都会被纪录到该文件中
- /etc/crontab:系统的例行性任务
- /etc/cron.hourly/*:让系统每小时定时 执行
- /etc/cron.daily/*:让系统每天定时执行
- /etc/cron.weekly/*:让系统每周定时执行
- /etc/cron.monthly/*:让系统每月定时执行
- /etc/cron.d/* 自己开发的软件可以放在该目录下
4.6. 一些注意事项
4.6.1. 资源分配不均的问题
当大量使用 crontab 的时候,总是会有问题发生的,最严重的问题就是“系统资源分配不均”的 问题
- 流量
- 区域内其他 PC 的流量侦测
- CPU 使用率
- RAM 使用率
- 线上人数实时侦测
-
如果每个流程都在同一个时间启动的话,那么在某个时段时,我的系统会变的相当的繁忙, 所以,这个时候就必须要分别设置
vim /etc/crontab 1,6,11,16,21,26,31,36,41,46,51,56 * * * * root CMD1 2,7,12,17,22,27,32,37,42,47,52,57 * * * * root CMD2 3,8,13,18,23,28,33,38,43,48,53,58 * * * * root CMD3 4,9,14,19,24,29,34,39,44,49,54,59 * * * * root CMD4
-
取消不要的输出项目
另外一个困扰发生在“ 当有执行成果或者是执行的项目中有输出的数据时,该数据将会 mail 给 MAILTO 设置的帐号
那么当有一个调度一直出错(例如 DNS 的侦测系统当中, 若 DNS 上层主机挂掉,那么你就会一直收到错误讯息!) ,可以直接以“数据流重导向”将输出的结果输出到 /dev/null 这个垃圾桶。
-
安全的检验
很多时候被植入木马都是以例行命令的方式植入的,所以可以借由检查 /var/log/cron 的内容 来视察是否有“非您设置的 cron 被执行了?”这个时候就需要小心一点啰!
-
周与日月不可同时并存
你可以分别以周或者是日月为单位作为循环,但你不可使用 「几月几号且为星期几」的模式工作”
5. 可唤醒停机期间的工作任务
如果你的linux服务器有一个每周星期天有一个重要的任务,但是这一周星期天停电,所以你只能周一去公司重启服务器。那么重启后服务还会不会执行呢。当然是不执行的,因为这个任务之后星期天会执行,其他时间不会执行。如果这个任务很重要必须执行呢?这时就需要使用anacron这个指令了。!这家伙可以主动帮你进行时间到了但却没有执行的调度。
5.1. 什么是anacron
anacron 并不是用来取代 crontab 的,anacron 存在的目的就在于我们上头提到的,在处理非 24 小时一直启动的 Linux 系统的 crontab 的执行! 以及因为某些原因导致的超过时间而没有 被执行的调度工作。
其实 anacron 也是每个小时被 crond 执行一次,然后 anacron 再去检测相关的调度任务有没 有被执行,如果有超过期限的工作在, 就执行该调度任务,执行完毕或无须执行任何调度 时,anacron 就停止了。
5.2. anacron与/etc/anacrontab
anacron 其实是一支程序并非一个服务!这支程序在 CentOS 当中已经进入 crontab 的调度,同时 anacron 会每个小时被主动执行一次。 anacron 的配置文件 应该放置在 /etc/cron.hourly
[Test@VM-24-3-centos ~]$ cat /etc/cron.hourly/0anacron
#!/bin/sh
# Check whether 0anacron was run today already
if test -r /var/spool/anacron/cron.daily; then
day=`cat /var/spool/anacron/cron.daily`
fi
if [ `date +%Y%m%d` = "$day" ]; then
exit 0
fi
# 上面的语法在检验前一次执行 anacron 时的时间戳记!
# Do not run jobs when on battery power
online=1
for psupply in AC ADP0 ; do
sysfile="/sys/class/power_supply/$psupply/online"
if [ -f $sysfile ] ; then
if [ `cat $sysfile 2>/dev/null`x = 1x ]; then
online=1
break
else
online=0
fi
fi
done
if [ $online = 0 ]; then
exit 0
fi
/usr/sbin/anacron -s
#所以其实也仅是执行 anacron -s 的指令
5.2.1. anacron的语法
[root@study ~]# anacron [-sfn] [job]..
[root@study ~]# anacron -u [job]..
选项与参数:
-s :开始一连续的执行各项工作 (job),会依据时间记录文件的数据判断是否进行;
-f :强制进行,而不去判断时间记录文件的时间戳记;
-n :立刻进行未进行的任务,而不延迟 (delay) 等待时间;
-u :仅更新时间记录文件的时间戳记,不进行任何工作。
job :由 /etc/anacrontab 定义的各项工作名称。
5.2.2. /etc/anacrontab
[Test@VM-24-3-centos ~]$ cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45 # 随机给予最大延迟时间,单位是分钟
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22 # 延迟多少个小时内应该要执行的任务时间
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly
天数 延迟时间 工作名称定义 实际要进行的指令串
- cron/ 内的时间纪录档) 相差的git天数,若超过此天数,就准备开始执行,若没有超过此天数,则不予执行后续的指令。
- 延迟时间:若确定超过天数导致要执行调度工作了,那么请延迟执行的时间,因为担心 立即启动会有其他资源冲突的问题吧!
- 工作名称定义:这个没啥意义,就只是会在 /var/log/cron 里头记载该项任务的名称这 样!通常与后续的目录资源名称相同即可。
- 实际要进行的指令串:有没有跟 0hourly 很像啊!没错!相同的作法啊!通过 run-parts 来处理的!
根据上面的配置文件内容,我们大概知道 anacron 的执行流程应该是这样的 (以 cron.daily 为例):
- 由 /etc/anacrontab 分析到 cron.daily 这项工作名称的天数为 1 天
- 由 /var/spool/anacron/cron.daily 取出最近一次执行 anacron 的时间戳记
- 由上个步骤与目前的时间比较,若差异天数为 1 天以上 (含 1 天),就准备进行指令
- 若准备进行指令,根据 /etc/anacrontab 的设置,将延迟 5 分钟 + 3 小时 (看 START_HOURS_RANGE 的设置);
- 延迟时间过后,开始执行后续指令,亦即“ run-parts /etc/cron.daily ”这串指令\
- 执行完毕后, anacron 程序结束
评论区