热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

crontab和anacron和logrotate的关系详解

服务器上的nginx使用logrotate来分割日志,设置为每天分割。但是logrotate似乎没有工作,日志并没有分割。服务器是CentOS6。为了找到原因
服务器上的nginx使用logrotate来分割日志,设置为每天分割。但是logrotate似乎没有工作,日志并没有分割。服务器是CentOS 6。

为了找到原因,我一步步的分析可能出错的地方。
如果是logrotate未执行,可能是crond没有启动,因为logrotate被/etc/cron.daily/logrotate脚本所启动,可以查看其中代码:

[root@test ~]# cat /etc/cron.daily/logrotate
#!/bin/sh

/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0

可以看到logrotate运行时加载配置文件logrotate.conf,而这个配置文件除了设定一些分割日志相关的选项,还包含分割日志的配置文件目录/etc/logrotate.d。
我的nginx的日志分割配置文件就保存在logrotate.d目录:

[root@test ~]# cat !$
cat /etc/logrotate.d/nginx
/root/*.log {
     Daily
    Missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 644 nobody nobody
    sharedscripts
    postrotate
    [ -f /usr/local/nginx/logs/nginx.pid ] && kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
    endscript
}

/root/*.log就是需要被分割的日志的目录,通配符*表示目录内的所有log文件都被分割,分割的规则就是{...}中的内容。这里把/root/*.log当做nginx日志只是为了测试。
在启动crond服务后,发现日志还是没有分割,于是想到会不会是/etc/logrotate.d/nginx配置文件的语法有问题,使用以下命令调试这个文件:

logrotate -vfd /etc/logrotate.d/nginx  # -vfd 三个选项分别表示显示详情,强制分割日志,只是调试配置文件而不是真的分割日志

输出结果表明有语法错误,Daily,Missingok 都应该是小写。改成daily,missingok。再次调试配置文件,可以正确分割日志:

[root@test ~]# ls -1 /root/
install-2017-5-14.log
install-2017-5-14.log-20170521  #logrotate归档的日志

上面我猜测是crond执行/etc/cron.daily/内的脚本,实现定时执行计划任务,包括执行logrotate日志分割。
为了验证是否正确,网上搜索一番后找到了答案。如果没有crontab命令,先安装:

yum install crontabs  #安装crond,crond实际上来自cronie包,这个包作为crontabs包的依赖被安装
chkconfig --add crond #添加到开机启动列表
chkconfig crond on    #开机启动crond服务
/etc/init.d/crond     #立即启动crond


以下文件或目录的作用:
cron计划任务有两种类型:
1)系统cron任务:由crond服务执行,/etc/crontab配置系统级别的任务
2)用户cron任务:由crond服务执行,用crontab命令编辑用户级别的任务

属于系统cron任务的文件或目录:
/etc/cron.d             #系统的任务脚本。执行 rpm -ql cronie 可以看到该目录被cronie包安装
/etc/cron.hourly     #每小时执行其内脚本。其中的0anacron文件调用anacron来执行任务,它被包cronie-anacron安装
/etc/cron.daily        #每天执行其内脚本。也被anacron执行其内脚本,logrotate调用脚本就在该目录内
/etc/cron.weekly     #每周执行其内脚本。
/etc/cron.monthly   #每月执行其内脚本。

控制用户cron任务的执行:
/etc/cron.allow   #默认不存在,如果这个文件存在,只有用户在这个文件中才能使用crontab命令
/etc/cron.deny    #将不可以使用crontab命令的用户写入其中

注意:cron.allow和cron.deny就是用户名的列表,每行一个用户名。比如 cron.deny中有一行jason,效果是如果当前登录用户是jason,执行 crontab -e会提示不允许使用crontab命令。


以下三个目录的作用:
/var/spool/cron/USER_NAME
#这个文件才是跟crontab -e/-l 关联的,这个文件保存了crontab -e编辑的任务内容
#比如执行 crontab -u root -e,编辑保存后,就会有/var/spool/cron/root 这个文件

/var/spool/anacron/{cron.daily,cron.monthly,cron.weekly}
#这三个文件记录了anacron上一次执行的时间(上一天,上一周或上一月)
#anacron任务执行时,对照这里的时间,决定是否执行anacron任务

/var/lib/logrotate.status
#这个文件记录logrotate执行情况,logrotate参考这个文件来决定是否需要rotate日志


crontab和anacron和logrotate的关系:

[root@test ~]# cat /etc/cron.d/0hourly   #这个文件指定每小时的01分执行/etc/cron.hourly内的所有脚本
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
01 * * * * root run-parts /etc/cron.hourly   #这里的root指定执行任务的用户,run-parts其实是一个可执行脚 本,在/usr/bin/run-parts,用来 执行cron.hourly目录内的所有脚本

说明:用crontab -e命令每次编辑完某个用户的cron设置后,cron自动在/var/spool/cron下生成一个与此用户同名的文件,此用户的cron信息都记录在这个文件中。cron启动后每过一份钟读一次这个文件,检查是否要执行里面的命令。因此此文件修改后不需要重新启动cron服务。cron服务每分钟不仅要读一次/var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也能运用cron服务做一些事情。用crontab命令配置是针对某个用户的,而编辑/etc/crontab是针对系统的任务。此文件的文件格式是:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin     #可执行文件查找路径
MAILTO=root      #如果出现错误,或者有数据输出,数据作为邮件发给这个帐号
HOME=/           #使用者运行的路径,这里是根目录

[root@test ~]# cat /etc/cron.hourly/0anacron    #cron.hourly目录下的脚本,根据条件执行anacron命令
#!/bin/bash
# Skip excecution unless the date has changed from the previous run
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

# Skip excecution unless AC powered
if test -x /usr/bin/on_ac_power; then
    /usr/bin/on_ac_power &> /dev/null
    if test $? -eq 1; then
    exit 0
    fi
fi
/usr/sbin/anacron -s

[root@test ~]# cat /etc/anacrontab    #如果执行anacron命令,那么接着查看anacron的配置文件
# /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     #只有在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

以上anacrontab配置文件最重要的是最后一部分,以这行为例:
1    5    cron.daily        nice run-parts /etc/cron.daily

表示每天都执行/etc/cront.daily/目录下的脚本文件,真实的延迟是RANDOM_DELAY+delay。这里的延迟是5分钟,加上上面的RANDOM_DELAY,所以实际的延迟时间是5-50之间,开始时间为03-22点,如果机器没关,那么一般就是在03:05-03:50之间执行。 nice命令将该进程设置为nice=10,默认为0,即低优先级进程。如果RANDOM_DELAY=0,那么表示准确延迟5min,即03:05执行cron.daily内的脚本。

[root@test ~]# cat /etc/cron.daily/logrotate   #最后在cron.daily内有logrotate的调用脚本
#!/bin/sh

/usr/sbin/logrotate /etc/logrotate.conf        #logrotate将会读取配置文件,最终会读取到/etc/logrotate.d/nginx
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0


当logrotate命令加载了/etc/logrotate.d/nginx配置文件时,还要比较nginx日志的归档日期:

[root@test ~]# cat /var/lib/logrotate.status | grep /root
"/root/install-2017-5-14.log" 2017-5-21   #如果今天是2017-5-21,这个文件里也是2017-5-21,说明今天已经归档过了,否则就会归档(分割)nginx日志

综上,整个逻辑流程为:
crond服务加载 /etc/cron.d/0hourly ---> 在每小时的01分执行/etc/cront.hourly/0anacron --->执行anacron --->根据/etc/anacrontab的配置执行/etc/cron.daily,/etc/cron.weekly,/etc/cron.monthly --->执行/etc/cron.daily/下的logrotate脚本 --->执行logrotate --->根据/etc/logrotate.conf配置执行脚本/etc/logrotate.d/nginx --->分割nginx日志成功


参考:
http://blog.chinaunix.net/uid-28794117-id-4338874.html
http://www.jb51.net/article/15008.htm
http://www.cnblogs.com/dingyingsi/archive/2013/04/16/3023623.html
https://zhidao.baidu.com/question/573078337.html
http://www.open-open.com/lib/view/open1483932198818.html
https://www.ibm.com/developerworks/cn/linux/l-anacron/index.html
http://blog.csdn.net/u010003835/article/details/52934649

推荐阅读
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 360SRC安全应急响应:从漏洞提交到修复的全过程
    本文详细介绍了360SRC平台处理一起关键安全事件的过程,涵盖从漏洞提交、验证、排查到最终修复的各个环节。通过这一案例,展示了360在安全应急响应方面的专业能力和严谨态度。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • CentOS 7 磁盘与文件系统管理指南
    本文详细介绍了磁盘的基本结构、接口类型、分区管理以及文件系统格式化等内容,并提供了实际操作步骤,帮助读者更好地理解和掌握 CentOS 7 中的磁盘与文件系统管理。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文深入探讨了如何通过调整InnoDB的关键配置参数来优化MySQL的随机IO性能,涵盖了缓存、日志文件、预读机制等多个方面,帮助读者全面提升数据库系统的性能。 ... [详细]
  • 本文详细分析了Hive在启动过程中遇到的权限拒绝错误,并提供了多种解决方案,包括调整文件权限、用户组设置以及环境变量配置等。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
  • 高效解决应用崩溃问题!友盟新版错误分析工具全面升级
    友盟推出的最新版错误分析工具,专为移动开发者设计,提供强大的Crash收集与分析功能。该工具能够实时监控App运行状态,快速发现并修复错误,显著提升应用的稳定性和用户体验。 ... [详细]
  • 该平台旨在为大型企业提供一个高效、灵活且可扩展的分布式微服务架构解决方案。它采用模块化、微服务化和热部署的设计理念,结合当前最先进且无商业限制的主流开源技术,如Spring Cloud、Spring Boot2、MyBatis、OAuth2和Element UI,实现前后端分离的系统管理平台。 ... [详细]
  • VSCode与Gitee集成:项目提交的高效实践
    本文介绍如何利用VSCode内置的Git工具将项目提交到Gitee,简化Git命令的使用,提升代码管理效率。同时分享一些常见的踩坑经验和解决方案。 ... [详细]
  • 微软Exchange服务器遭遇2022年版“千年虫”漏洞
    微软Exchange服务器在新年伊始遭遇了一个类似于‘千年虫’的日期处理漏洞,导致邮件传输受阻。该问题主要影响配置了FIP-FS恶意软件引擎的Exchange 2016和2019版本。 ... [详细]
  • 本文介绍如何在现有网络中部署基于Linux系统的透明防火墙(网桥模式),以实现灵活的时间段控制、流量限制等功能。通过详细的步骤和配置说明,确保内部网络的安全性和稳定性。 ... [详细]
  • 本文深入探讨了 Redis 的两种持久化方式——RDB 快照和 AOF 日志。详细介绍了它们的工作原理、配置方法以及各自的优缺点,帮助读者根据具体需求选择合适的持久化方案。 ... [详细]
author-avatar
小葵小小葵_530
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有