linux系统管理
一、进程管理
1、进程简介
1)、什么是进程管理?
那么到底什么是进程呢?进程是正在执行的一个程序或命令,每一个进程都是一个运行的实体,都有自己的地址空间,并占用一定的系统资源。那么什么是程序呢?程序是人使用计算机语言编写的可以实现特定目标或解决特定问题的代码集合。这么讲很难理解,那我们换一种说法:
- 程序是人使用计算机语言编写的,可以实现一定功能,并且可以执行的代码集合。
- 进程是正在执行当中的程序。程序被执行时,执行人的权限和属性、以及程序的代码都会被加载如内存,操作系统给这个进程分配一个ID号,我们成为PID(进程ID)。
2)、进程管理的作用
- 判断服务器健康状态:运维工程师最主要的工作就是保证服务器安全稳定的运行。理想的状态是,在服务器出现问题,但是还没有造成服务器宕机或停止服务时,就人为干预解决了问题。进程管理最主要的工作就是判断服务器当前运行是否健康,是否需要人为干预。如果服务器的CPU占用率、内存占用率过高,就需要人为介入解决问题了。
- 查看系统中所有的进程:我们需要查看系统中所有正在运行的进程,通过这些进程可以判断系统中运行了哪些服务,是否有非法服务运行。
- 杀死进程:这是进程管理中最不常用的手段,当我需要停止服务时,会通过正确关闭命令来停止服务(如apache服务可以通过service httpd stop来关闭)。只有当正确终止进程的手段失效的情况下,才会考虑使用kill命令杀死进程(你不是杀手,不要什么进程都用kill来终止,否则非常容易导致服务器崩溃)。
2、进程的查看
1)、 ps命令
ps命令是用来静态显示系统中进程的命令。不过这个命令有些特殊,它的部分命令的选项不能加入“-”,比如命令“ps aux”,其中“aux”是选项,但是这个选项不能加入“-”。这是因为ps命令的部分选项需要遵守BSD操作系统的格式。所以ps命令的常用选项的组合是固定的。命令如下:
1 | [root@localhost ~]# ps aux |
1 | [root@localhost ~]# ps aux |
解释下这个命令的输出:
USER:该进程是由哪个用户产生的;
PID:进程的ID号;
%CPU:该进程占用CPU资源的百分比,占用越高,进程越耗费资源;
%MEM:该进程占用物理内存的百分比,占用越高,进程越耗费资源;
VSZ:该进程占用虚拟内存的大小,单位KB;
RSS:该进程占用实际物理内存的大小,单位KB;
TTY:该进程是在哪个终端中运行的。其中tty1-tty7代表本地控制台终端(可以通过alt+F1-F7键切换不同的终端),tty1-tty6是本地的字符界面终端,tty7是图形终端。pts/0-255代表虚拟终端,一般是远程连接的终端,第一个远程连接占用的是pts/0终端,第二个远程连接占用pts/1,依次增长。
STAT:进程状态。常见的状态有:
D:不可被唤醒的睡眠状态,通常用于I/O情况
R:该进程正在运行
S:该进程在睡眠状态,可被唤醒
T:停止状态,可能是在后台暂停或进程在除错状态
W:内存交互状态(从2.6内核开始无效)
X:死掉的进程(应该不会出现)
Z:僵尸进程。进程已经终止,但是部分程序还在内存当中。
<:高优先级(以下状态在BSD格式当中出现)
N:低优先级
L:被锁入内存
s:包含子进程
l:多线程(小写L)
+:位于后台
START:该进程的启动时间
TIME:该进程占用CPU的运算时间,注意不是系统时间
COMMAND:产生此进程的命令名
1 | [root@localhost ~]# ps -le |
也来解释下这个命令的输出:
F:进程标志,说明进程的权限,常见的标志有:
- 1:进程可以复制,但是不能执行
- 4:进程使用超级用户权限
S:进程状态。具体的状态和“ps aux”命令中STAT状态一致
UID:进程是哪个UID用户调用运行的
PID:进程的ID号
PPID:父进程的ID号
C:该进程的CPU使用率,单位是百分比PRI:进程的优先级,数值越小该进程优先级越高,越快被CPU执行NI:进程的优先级,也是数值越小越早被执行
ADDR:该进程在内存的哪个位置
SZ:该进程占用多大内存
WCHAN:该进程是否运行。“-”代表正在运行
TTY:该进程由哪个终端产生
TIME:该进程占用CPU的运算时间,注意不是系统时间
CMD:产生此进程的命令名
2)、 top命令
1 | [root@localhost ~]# top [选项] |
我们看看top命令的执行结果:
1 | [root@localhost ~]# top |
我们解释下命令的输出,top命令的输出内容是动态的,默认每3秒刷新一次。命令的输出主要分为两大部分:第一部分是前五行,显示的是整个系统的资源使用状况,我们就是通过这些输出判断服务器的健康状态;第二部分从第六行开始,显示的是系统中进程的信息。
- 我们先来说明第一部分的作用:
第一行信息为任务队列信息,具体内容如表所示:
内容 | 说明 |
---|---|
12:26:46 | 系统当前时间 |
up 1 day, 13:32 | 系统的运行时间,本机已经运行1天13小时32分钟 |
2 users | 当前登录了两个用户 |
load average: 0.00, 0.00, 0.00 | 系统在之前1分钟,5分钟,15分钟的平均负载。如果CPU是单核,则这个数超过1,就是高负载。如果CPU是四核,则这个数超过4,就是高负载。(这个平均负载完全是个人经验来进行判断的,一般认为不应该超过服务器CPU的核数。) |
第二行为进程信息,具体内容如表所示:
内容 | 说明 |
---|---|
Tasks: 95 total | 系统中的进程总数 |
1 running | 正在运行的进程数 |
94 sleeping | 睡眠的进程 |
0 stopped | 正在停止的进程 |
0 zombie | 僵尸进程。如果不是0,需要手工检查僵尸进程 |
第三行为CPU信息,具体内容如表所示:
内容 | 说明 |
---|---|
Cpu(s): 0.1%us | 用户模式占用的CPU百分比 |
0.1%sy | 系统模式占用的CPU百分比 |
0.0%ni | 改变过优先级的用户进程占用的CPU百分比 |
99.7%id | 空闲CPU的CPU百分比 |
0.1%wa | 等待输入/输出的进程的占用CPU百分比 |
0.0%hi | 硬中断请求服务占用的CPU百分比 |
0.1%si | 软中断请求服务占用的CPU百分比 |
0.0%st | st(Steal time)虚拟时间百分比。就是当有虚拟机时,虚拟CPU等待实际CPU的时间百分比。 |
第四行为物理内存信息,具体内容如表所示:
内容 | 说明 |
---|---|
Mem: 625344k total | 物理内存的总量,单位KB |
571504k used | 已经使用的物理内存数量 |
53840k free | 空闲的物理内存数量,我们使用的是虚拟机,总共只分配了628MB内存,所以只有53MB的空闲内存了 |
65800k buffers | 作为缓冲的内存数量 |
第五行为交换分区(swap)信息
内容 | 说明 |
---|---|
Swap: 524280k total | 交换分区(虚拟内存)的总大小 |
0k used | 已经使用的交互分区的大小 |
524280k free | 空闲交换分区的大小 |
409280k cached | 作为缓存的交互分区的大小 |
- 再来看top命令的第二部分输出,主要是系统进程信息。这部分和ps命令的输出比较类似,只是如果在终端中执行top命令不能看到所有的进程,而只能看到占比靠前的进程。
- PID:进程ID
- USER:该进程所属的用户
- PR:优先级,数值越小优先级越高
- NI:优先级,数值越小优先级越高VIRT:该进程使用的虚拟内存的大小,单位KB
- RES:该进程使用的物理内存的大小,单位KB
- SHR:共享内存大小,单位KB
- S:进程状态
- %CPU:该进程占用CPU的百分比
- %MEM:该进程占用内存的百分比
- TIME+:该进程总共占用的CPU时间
- COMMAND:进程的命令名
接下来我们举几个top命令常用的实例,来继续说明下top命令。比如我如果只想让top命令查看某一个进程,这时就可以使用“-p选项”:
1 | [root@localhost ~]# top -p 15273 |
在top命令的交互界面中按“q”键会退出top命令。也可以按“?”或“h”得到top命令交互界面的帮助信息。也可以按“k”键终止某个进程,命令如下:
1 | [root@localhost ~]# top |
如果在操作终端执行top命令,并不能看到系统中所有的进程,默认看到的只是CPU占比靠前的进程。如果我们想要看到所有的进程可以把top命令的结果重定向到文件当中即可。不过top命令是持续运行的,这时就需要“-b”和“-n”选项了,具体命令如下:
1 | [root@localhost ~]# top -b -n 1 > /root/top.log |
3)、 pstree命令
1 | [root@localhost ~]# pstree [选项] |
3、进程的管理
系统中可以识别的信号较多,我们可以使用命令“kill -l”或“man 7 signal”来查询,命令如下:
1 | [root@localhost ~]# kill -l |
这里我们介绍一下主要的信号,如表所示:
信号代号 | 信号名称 | 说明 |
---|---|---|
1 | SIGHUP | 该信号让进程立即关闭,然后重新读取配置文件之后重启。 |
2 | SIGINT | 程序终止信号,用于终止前台进程。相当于输出ctrl+c快捷键。 |
8 | SIGFPE | 在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢出及除数为0等其它所有的算术的错误。 |
9 | SIGKILL | 用来立即结束程序的运行. 本信号不能被阻塞、处理和忽略。一般用于强制终止进程。 |
14 | SIGALRM | 时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该信号。 |
15 | SIGTERM | 正常结束进程的信号,kill命令的默认信号。有时如果进程已经发生问题,这个信号是无法正常终止进程的,我们才会尝试SIGKILL信号,也就是信号9。 |
18 | SIGCONT | 该信号可以让暂停的进程恢复执行,本信号不能被阻断。 |
19 | SIGSTOP | 该信号可以暂停前台进程,相当于输入ctrl+z快捷键。本信号不能被阻断。 |
3)、 kill命令
1 | [root@localhost ~]# kill [信号] PID |
1 | 例2:使用“-1”信号,让进程重启 |
1 | 例3:使用“-19”信号,让进程暂停。 |
2)、killall命令
1 | [root@localhost ~]# killall [选项][信号] 进程名 |
1 | 交互式杀死sshd进程 |
3 )、pkill命令
pkill命令和killall命令非常类似,也是按照进程名来杀死进程。格式如下:
1 | [root@localhost ~]# pkill [选项] [信号] 进程名 |
1 | [root@localhost ~]# pkill -9 -t pts/1 |
二、工作管理
1、工作管理简介
后台管理有几个事项需要大家注意:
- 前台是指当前可以操控和执行命令的这个操作环境,后台是指工作可以自行运行,但是不能直接用ctrl+c来终止它,只能使用fg/bg来调用工作;
- 当前的登录终端,只能管理当前终端的工作,而不能管理其他登录终端的工作。如tty1登录的终端是不能管理tty2终端中的工作的;
- 放入后台的命令必须可以持续运行一段时间,这样我们才能扑捉和操作这个工作。如果把ls命令放入后台执行,它很快就会执行完成,我们很难操作它。
- 放入后台执行的命令不能和前台用户有交互或需要前台输入,否则放入后台只能暂停,而不能执行。比如vi命令放入后台只能暂停,而不能执行,因为vi需要前台输入信息。top命令也不能放入后台执行,而只能放入后台暂停,因为top命令需要和前台有交互。
2、如何把命令放入后台
那么我们如何把命令放入后台呢?有两种方法,分别如下:
1)、第一种方法是“命令 &”,把命令放入后台执行
第一种把命令放入后台的方法是在命令后面加入“空格&”,这种方法放入后台的命令,在后台是执行状态。但是注意,放入后台执行的命令不能与前台有交互,否则这个命令是不能在后台执行的。
举个例子:
1 | [root@localhost ~]# find / -name install.log & |
这样的话,虽然find命令在执行,但是当前终端我还是可以进行其他命令操作的。如果在终端上出现:
1 | [1]+ Done find / -name install.log |
证明后台这个任务已经完成了,当然命令如果有执行结果的话,也会显示到操作终端上。[1]是这个命令的工作号,+号代表这个任务是最近一个被放入后台的工作。
2)、第二种方法是在命令执行过程中按ctrl+z快捷键,命令在后台是暂停状态
使用这种方法放入后台的命令,就算是不和前台有交互,能在后台执行的命令,也是暂停状态,ctrl+z快捷键就是暂停的快捷键。举几个例子:
1 | 例1: |
3、后台命令管理
1)、查看后台的工作
1 | [root@localhost ~]# jobs |
2)、将后台暂停的工作恢复到前台执行
1 | [root@localhost ~]# fg %工作号 |
3)、把后台暂停的工作恢复到后台执行
1 | [root@localhost ~]# bg %工作号 |
4)、后台命令脱离登录终端运行
我们已经知道把命令放入后台,只能在当前登录终端执行。那如果我是远程管理的服务器,在远程终端中执行了后台命令,这时我退出登录,这个后台命令还能继续执行吗?当然是不行的,这个后台命令会被终止。但是我们确实需要在远程终端中执行某些后台命令,该如何执行呢?
第一种方法是把需要后台执行的命令加入/etc/rc.local文件,让系统在启动时执行这个后台程序。这种方法的问题是,服务器时不能随便重启的,万一有临时后台任务,就不能执行。
第二种方法是使用系统定时任务,让系统在指定的时间执行某个后台命令。这样放入后台的命令与终端无关,是不依赖登录终端的。
最后一种方法是使用nohup命令。
nohup命令的作用就是让后台工作在离开操作终端时,也能够正确的在后台执行。命令的格式如下:
1 | [root@localhost ~]# nohup [命令] & |
三、系统资源查看
1、vmstat命令监控系统资源
1 | [root@localhost ~]# vmstat [刷新延时刷新次数] |
解释下这个命令的输出:
procs:进程信息字段:
- r:等待运行的进程数,数量越大,系统越繁忙。
- b:不可被唤醒的进程数量,数量越大,系统月繁忙。
memory:内存信息字段:
- swpd:虚拟内存的使用情况,单位KB。
- free:空闲的内存容量,单位KB。
- buff:缓冲的内存容量,单位KB。
- cache:缓存的内存容量,单位KB。
swap:交换分区的信息字段:
- si:从磁盘中交换到内存中数据的数量,单位KB。
- so:从内存中交换到磁盘中数据的数量,单位KB。此两个数越大,证明数据需要经常在磁盘和内存之间交换,系统性能越差。
io:磁盘读写信息字段:
- bi:从块设备读入数据的总量,单位是块。
- bo:写到块设备的数据的总量,单位是块。此两个数越大,代表系统的I/O越繁忙。
system:系统信息字段:
- in:每秒被中断的进程次数。
- cs:每秒钟进行的事件切换次数。此两个数越大,代表系统与接口设备的通信非常繁忙。
CPU:CPU信息字段:
- us:非内核进程消耗CPU运算时间的百分比。
- sy:内核进程消耗CPU运算时间的百分比。
- id:空闲CPU的百分比。
- wa:等待I/O所消耗的CPU百分比。
- st:被虚拟机所盗用的CPU占比。
2、dmesg显示开机时内核检测信息
1 | 例如: |
3、free命令查看内存使用状态
1 | [root@localhost ~]# free [-b|-k|- m|-g] |
解释下这个命令:
第一行:total是总内存数,used是已经使用的内存数,free是空闲的内存数,shared是多个进程共享的内存总数,buffers是缓冲内存数,cached是缓存内存数。默认单位是KB。
第二行:-/buffers/cache的内存数,相当于第一行的used-buffers-cached。+/buffers/cache的内存数,相当于第一行的free+buffers+cached。
第三行:total是swap的总数;used是已经使用的swap数,free是空闲的swap数。默认单位是KB。
4、查看CPU信息
CPU的主要信息保存在/proc/cpuinfo这个文件当中,我们只要查看这个文件,就可以知道cpu的相关信息。命令如下:
1 | [root@localhost ~]# cat /proc/cpuinfo |
5、查看本机登陆用户信息
如果我们想要知道Linux服务器上目前已经登录的用户信息,可以使用w或who命令来进行查询。先看看w命令,命令格式如下:
1 | [root@localhost ~]# w |
解释下这个命令的结果:
- 第一行其实和top命令的第一行非常类似,主要显示了系统当前时间,开机多久(up),有多少用户登陆(users),1分钟、5分钟、15分钟前的平均负载(load average)。
- 第二行是项目的说明,第三行开始每行代表一个用户。这些项目是:
- USER:登陆的用户名;
- TTY:登陆终端;
- FROM:从哪个IP地址登陆;
- LOGIN@:登陆时间;
- IDLE:用户闲置时间;
- JCPU:指的是和该终端连接的所有进程占用的CPU运算时间。这个时间里并不包括过去的后台作业时间,但却包括当前正在运行的后台作业所占用的时间;
- PCPU: 是指当前进程所占用的CPU运算时间;
- WHAT:当前正在运行的命令。
who命令比w命令稍微简单一点,也可以用来查看系统中已经登录的用户。命令如下:
1 | [root@localhost ~]# who |
6、uptime命令
uptime命令的作用就是显示系统的启动时间和平均负载,也就是top命令的第一行。其实w命令也能看到这一行的数据,具体原意使用哪个命令看个人习惯。命令如下:
1 | [root@localhost ~]# uptime |
7、查看系统与内核相关信息
我们使用uname命令查看内核的相关信息,命令如下:
1 | [root@localhost ~]# uname [选项] |
如果我们想要判断当前系统的位数,可以通过file命令来判断系统文件(主要是系统命令)的位数来推断系统的位数。命令如下:
1 | [root@localhost ~]# file /bin/ls |
如果我们想要查询当前Linux系统的发行版本,可以使用“lsb_release -a”命令查看,命令如下:
1 | [root@localhost ~]# lsb_release -a |
四、系统定时任务
1、at一次性执行定时任务
1)、 at服务管理与访问控制
at命令要想正确执行,需要atd服务的支持。atd服务是独立的服务,所以启动的命令是:
1 | [root@localhost ~]# service atd start |
如果想要让atd服务开机时自动启动,可以使用如下命令:
1 | [root@localhost ~]# chkconfig atd on |
atd服务启动之后,at命令才可以正常使用,不过我们还要学习下at命令的访问控制。这里的访问控制指的是允许哪些用户使用at命令设定定时任务,或者不允许哪些用户使用at命令。大家可以想象成为设定黑名单或设定白名单,这样更容易理解。at的访问控制是依靠/etc/at.allow文 件( 白名单)和/etc/at.deny文件(黑名单)这两个文件来实现的,具体规则如下:
- 如果系统中有/etc/at.allow文件,那么只有写入/etc/at.allow文件(白名单)中的用户可以使用at命令,其他用户不能使用at命令(/etc/at.deny文件会被忽略,也就是说同一个用户既写入/etc/at.allow文件,也写入/etc/at.deny文件,那么这个用户是可以使用at命令的,因为/etc/at.allow文件优先级更高。)。
- 如果系统中没有/etc/at.allow文件,只有/etc/at.deny文件,那么写入/etc/at.deny文件(黑名单)中的用户不能使用at命令,其他用户可以使用at命令。不过这个文件对root用户不生效。
- 如果系统中这两个文件都不存在,那么只有root用户可以使用at命令。
系统中默认时只有/etc/at.deny文件,而且这个文件是空的,这样的话系统中所有的用户都可以使用at命令。不过如果我们打算控制用户的at命令权限,把用户写入/etc/at.deny文件即可
/etc/at.allow文件的权限更高,如果/etc/at.allow文件存在,则/etc/at.deny文件失效。/etc/at.allow管理行为更加严格,因为只有写入这个文件的用户才能使用at命令,如果需要禁用at命令的用户较多,则可以把少数用户写入这个文件。/etc/at.deny文件的管理较为松散,如果允许使用at命令的用户较多,则可以把禁用的用户写入这个文件。不过这两个文件都不能对root用户生效。
2)、at命令
1 | [root@localhost ~]# at [选项] 时间 |
at命令只要指定正确的时间,就可以输入需要在指定时间执行的命令了,这个命令可以是系统命令,也可以是shell脚本。举几个例子吧:
1 | 例子1: |
3)、其他at管理命令
at还有查询和删除命令,命令如下
1 | [root@localhost ~]# atq |
2、crontab循环执行定时任务
1)、 crond服务管理与访问控制
crontab命令是需要crond服务支持的,crond服务同样是独立的服务,所以启动和自启动方法如下:
1 | [root@localhost ~]# service crond restart |
crond服务默认是自启动的,如果服务器上有循环执行的系统定时任务,就不要关闭crond服务了。
crontab命令和at命令类似,也是通过/etc/cron.allow和/etc/cron.deny文件来限制某些用户是否可以使用crontab命令的。而且原则也非常相似:
- 当系统中有/etc/cron.allow文件时,只有希尔此文件的用户可以使用crontab命令,没有写入的用户不能使用crontab命令。同样如果有此文件,/etc/cron.deny文件会被忽略,/etc/cron.allow文件的优先级更高。
- 当系统中只有/etc/cron.deny文件时,则写入此文件的用户不能使用crontab命令,没有写入文件的用户可以使用crontab命令。
这个规则基本和at的规则一直,同样/etc/cron.allow文件的优先级比/etc/cron.deny文件的优先级高,Linux中默认只有/etc/cron.deny文件。
2)、用户的crontab设置
每个用户都可以实现自己的crontab定时任务,只要是使用这个用户身份执行“crontab -e”命令即可,当然这个用户不能加入/etc/cron.deny文件中。crontab命令格式如下:
1 | [root@localhost ~]# crontab [选项] |
1 | [root@localhost ~]# crontab -e |
项目 | 含义 | 范围 |
---|---|---|
第一个“*” | 一小时当中的第几分钟 | 0-59 |
第二个“*” | 一天当中的第几小时 | 0-23 |
第三个“*” | 一个月当中的第几天 | 1-31 |
第四个“*” | 一年当中的第几月 | 1-12 |
第五个“*” | 一周当中的星期几 | 0-7(0和7都代表星期日) |
在时间表示时,还有一些特殊符号需要学习,如表所示:
特殊符号 | 含义 |
---|---|
* | 代表任何时间。比如第一个“*”就代表一小时中每分钟都执行一次的意思。 |
, | 代表不连续的时间。比如“0 8,12,16 * * * 命令”,就代表在每天的8点0分,12点0分,16点0分都执行一次命令 |
- | 代表连续的时间范围。比如“0 5 * * 1-6命令”,代表在周一到周六的凌晨5点0分执行命令 |
*/n | 代表每隔多久执行一次。比如“*/10 * * * * 命令”,代表每隔10分钟就执行一遍命令 |
举例
时间 | 含义 |
---|---|
45 22 * * * 命令 | 在22点45分执行命令 |
0 17 * * 1 命令 | 每周1 的17点0分执行命令 |
0 5 1,15 * * 命令 | 每月1号和15号的凌晨5点0分执行命令 |
40 4 * * 1-5 命令 | 每周一到周五的凌晨4点40分执行命令 |
*/10 4 * * * 命令 | 每天的凌晨4点,每隔10分钟执行一次命令 |
0 0 1,15 * 1 命令 | 每月1号和15号,每周1的0点0分都会执行命令。注意:星期几和几号最好不要同时出现,因为他们定义的都是天。非常容易让管理员混乱。 |
1 | 例子1:让系统每隔5分钟,就向/tmp/test文件中写入一行“11”,验证一下系统定时任务是否会执行 |
3)、 crontab的注意事项
在书写crontab定时任务时,需要注意几个注意事项,这里我们再强调下:
- 六个选项都不能为空,必须填写。如果不确定使用“*”代表任意时间;
- crontab定时任务,最小有效时间是分钟,最大时间范围是月。像2018年某时执行,3点30分30秒这样的时间都不能识别;
- 在定义时间时,日期和星期最好不要在一条定时任务中出现,因为它们都是以天作为单位,非常容易让管理员混乱;
- 在定时任务中,不管是直接写命令,还是在脚本中写命令,最好都是用绝对路径。有时相对路径的命令会报错。
4、系统的crontab设置
“crontab -e”是每个用户执行的命令,也就是说不同的用户身份可以执行自己的定时任务。可是有些定时任务需要系统执行,这时我们就需要编辑/etc/crontab这个配置文件了。当然,并不是说写入/etc/crontab配置文件中的定时任务执行时,不需要用户身份,而是“crontab -e”命令定义定时任务时,默认用户身份是当前登录用户。而修改/etc/crontab配置文件时,定时任务的执行着身份是可以手工指定的。这样定时任务的执行会更加灵活,修改起来也更加方便。
那我们打开这个文件看看吧:
1 | [root@localhost ~]# vi /etc/crontab |
在CentOS 6.x中,/etc/crontab这个文件也发生了变化,在CentOS 5.x中这个文件的内容大概是这个样子:
1 | #以下输出,是在CentOS 5.5当中 |
在CentOS 5.x版本中,/etc/crontab文件会使用run-parts脚本执行/etc/cron.{daily,weekly,monthly}目录中的所有文件。这个run-parts其实是一个shell脚本,保存在/usr/bin/run-parts,它的作用就是把其后面跟随的目录中的所有可执行文件依次执行。也就是说,如果我们想让某个脚本在每天都执行一次,可以不用手工去写定时任务,而只需要给这个脚本赋予执行权限,并把它放入/etc/cron.daily/目录中。这样这个脚本就会在每天的凌晨4点02分执行了。
可是在CentOS 6.x版本中,/etc/crontab文件中不再有相关的段落,那么是否run- ptars这种定时任务执行方法不可用了呢?我们看到/etc/crontab中有一句提示,让我们“man 4 crontabs”来查看帮助,那么我们就看看这个帮助吧!在这个帮助中,明确写明了“在旧版本的crontab配置文件中,是通过run -parts脚本来调用cron.{daily,weekly,monthly}目录,定时执行这些目录中的脚本。在当前系统中,为了避免cron和anacron之间产生冲突,只要anacron已经安装,就使用anacron来执行这些目录中的脚本。具体可以查看anacron(8)的帮助。”。对于anacron的用法,我们下一个小节来介绍。
其实对我们用户来讲,我们并不需要知道这个定时任务到底是由哪个程序调用的。我们需要知道的事情是如何使用系统的crontab设置。这个新老版本的CentOS没有区别,配置方法都有两种:
- 第一种方法就是我刚刚说过的,把你需要定时执行的工作写成脚本程序,并赋予执行权限,然后直接把这个脚本复制到/etc/cron.{daily,weekly,monthly}目录中的任意一个。比如我需要让某个脚本每周执行,那么就把这个脚本复制到/etc/cron.weekly/目中中。这样这个脚本就会每周执行一次,具体的执行时间要参考anacron的配置。
- 第二种方法就是修改/etc/crontab这个配置文件,自己加入自己的定时任务,不过需要注意指定脚本的执行者身份。例如:
1 | [root@localhost ~]# vi /etc/crontab |
只要保存/etc/crontab文件,这个定时任务就可以执行了,当然要确定crond服务是运行的。这两种方法都是可以使用的,具体看个人的习惯吧!不过要想修改/etc/crontab文件,当然我要是root用户才可以,普通不能修改,只能使用用户身份的crontab命令。
3、anacron
anacron是用来干什么的呢?我们的Linux服务器如果不是24小时开机的,那么刚好在关机的时间段之内有系统定时任务(cron)需要执行,那么这些定时任务是不会执行的。也就是说,假设我们需要在凌晨5点05分执行系统的日志备份,但是我们的Linux服务器不是24小时开机的,在晚上需要关机,白天上班之后才会再次开机。这个定时任务的执行时间我们的服务器刚好没有开机,那么这个任务就不会执行了。anacron就是用来解决这个问题的。
anacron会使用一天,七天,一个月作为检测周期,用来判断是否有定时任务在关机之后没有执行,如果有这样的任务,anacron会在特定的时间重新执行这些定时任务。那么anacron是如何判断这些定时任务已经超过了执行时间呢?在系统的/var/spool/anacron/目录中存在cron.{daily,weekly,monthly}文件,这些文件中都保存着anacron上次执行时的时间。anacron会去读取这些文件中的时间,然后和当前时间做比较,若果两个时间的差值超过了anacron的指定时间差值(一般是1天,7天和一个月),就说明有定时任务漏掉了没有被执行,这时anacron会介入而执行这个漏掉的定时任务,从而保证在关机时没有被执行的定时任务不会被漏掉。
在CentOS 6.x中,我们使用cronie-anacron取代了vixie-cron软件包。而且在原先的CentOS版本中/etc/cron.{daily,weekly,monthly}这些目录中的定时任务会同时被cron和anacron调用,这样非常容易出现重复执行同一个定时任务的错误。在现在的CentOS 6.x中,/etc/cron.{daily,weekly,monthly}目录中的定时任务程序只会被anacron调用,从而保证这些定时任务只会在每天、每周或每月被定时执行一次,而不会重复执行。这也是我们在上一个小节中介绍的CentOS 6.x的变化之一。
在CentOS 6.x中anacron还有一个变化,anacron不再是单独的服务,而变成了系统命令。也就是说我们不再可以使用“service anacron restart”命令来管理anacron服务了。而是需要使用anacron命令来管理anacron工作,具体命令如下:
1 | [root@localhost ~]# anacron [选项] [工作名] |
在我们当前的Li nux中,其实不需要执行任何anacron命令,只需要配置好/etc/anacrontab文件,系统就会依赖这个文件中的设定来通过anacron执行定时任务。那么关键就是/etc/anacrontab文件的内容了,这个文件如下:
1 | [root@localhost ~]# vi /etc/anacrontab |
这个文件中“RANDOM_DELAY”定义的是最大随机延迟,也就是说cron.daily任务如果超过1天没有执行,并不会马上执行,而是先延迟强制延迟时间之后,再延迟随机延迟时间之后再执行命令。“START_HOURS_RANGE”定义anacron的执行时间范围,anacron只会在这个时间范围之内执行。
我们用cron.daily工作来说明下/etc/anacrontab的执行过程:
- 首先读取/var/spool/anacron/cron.daily中的上一次anacron执行的时间;
- 和当前时间比较,如果两个时间的差值超过1天,就执行cron.daily工作;
- 执行这个工作只能在03:00-22:00之间;
- 执行工作时强制延迟时间为5分钟,再随机延迟0-45分钟时间;
- 使用nice命令指定默认优先级,使用run- parts脚本执行/etc/cron.daily目录中的所有可执行文件。
大家发现了吧,/etc/cron.{daily,weekly,monthly}中的脚本,在当前的Linux中是被anacron调用的,不再依靠cron服务。不过anacron不用设置多余的配置,我们只需要把需要定时执行的脚本放入/etc/cron.{daily,weekly,monthly}目录当中,就会每天、每周或每月执行,而且也不再需要启动anacron服务了。我们如果做修改的话,只用修改/etc/anacrontab配置文件即可。比如我更加习惯让定时任务在凌晨03:00-05:00执行,就可以如下修改:
1 | [root@localhost ~]# vi /etc/anacrontab |
这样我们所有放入/etc/cron.{daily,weekly,monthly}目录中的脚本都会在指定时间运行了,而且也不怕服务器万一关机的情况了。