为什么apache每天凌晨3点会自动重启

朋友发了一个日志截图给我,说我服务器上的apache每天凌晨3点左右会重启啊?怎么回事?

apache-er1

仿佛代志很大条是吧,其实没那么严重。现在教学时间到,咳。

先看一下这条日志信息。几个要点:

  1. SIGUSR1 received,这说明是收到了一个USR1信号。猜测应该是别的什么进程或是哪个管理员用kill发的(kill不是光用来杀进程的好吗?)
  2. graceful restart,说明是一个很graceful的restart,具体怎么个graceful,后面说。

怎么找原因,我的步骤。

  1. 看httpd日志情况
    进服务器,找到httpd日志,它的目录是这样的
    apache-er2
    很有意思是吧,gz日志的生成时间也在3点多是吧。而且都是按日期生成的。
    我们知道在httpd配置里,一般我们写日志是写到access_log和error_log文件里,而没有去做一个按日期打包的动作,然后服务器管理员肯定也不会上来每天手动打包一次,那么是谁在做这个“自动按天打包”的事儿呢?logrotate。
    它是做什么用的呢,找一下手册就知道了(man logrotate)。

    logrotate ‐ rotates, compresses, and mails system logs

    logrotate  is  designed to ease administration of systems that generate large numbers of log files.  It allows automatic rotation, compression, removal, and mailing of log files.  Each log file may be handled daily, weekly, monthly, or when it grows too large.
           Normally, logrotate is run as a daily cron job.  It will not modify a log more than once in one day unless the criterion for that log is based on the  log’s  size  and logrotate is being run more than once each day, or unless the -f or –force option is used.
           Any  number  of  config files may be given on the command line. Later config files may override the options given in earlier files, so the order in which the logrotate config files are listed is important.  Normally, a single config file which includes any other config files which are needed should be used.  See below for more information on how to use the include directive to accomplish this.  If a directory is given on the command line, every file in that directory is used as a config file.
           If  no  command line arguments are given, logrotate will print version and copyright information, along with a short usage summary.  If any errors occur while rotating logs, logrotate will exit with non-zero status.

    简单讲,logrotate就是把系统日志做切分的,就是rotate。
    为什么叫rotate而不是cut或是split呢?因为默认情况下,它会把一个xxx.log切分成比如xxx.log.1, 写满之后就会写到xxx.log.2, 再满之后写到xxx.log.3,再满之后写到xxx.log.4,再满之后写到xxx.log.5 这样。然后如果还不够的话,xxx.log.1就会被重新写入。这样最多只有这么几个文件,用来省磁盘空间。这样就是一个循环的过程,所以才叫rotate。
    好了,回到logrotate来。

  2. 看logrotate
    logrotate一般是跟着系统定时任务crontab跑的。
    然后就去看了一下crontab的任务列表。crontab -l,没看到和logrotate相关的。
    就去crontab的目录下找了一下。
    apache-er3
    很容易猜到cron.daily,cron.hourly是做啥用的吧?一个好的命名多么重要啊,然后猜测也很重要是吧。
    进cron.daily,看到这个
    apache-er4
    你看是吧。然后查看一下这个logrotate是什么,啥,怎么看?cat或less啊。为什么不敢看,二进制也可以看啊,为什么不敢查看这是什么玩意?查看又不是执行,不要怕啦亲。
    apache-er5
    很简单的shell脚本。可以看到logrotate使用了一个配置文件/etc/logrotate.conf
    配置文件限制了程序的表现,所以如果想知道它是怎么运行的,查一下配置文件是怎么写的就好了。
  3. 查看logrotate的配置文件
    apache-er6
    看不懂的都略过吧,好像什么和httpd日志关联的都没有是吧,但你看到了include /etc/logrotate.d是吧,然后就进/etc/logrotate.d看看有什么好乏?
    apache-er7
    可以看到一堆文本文件。等等,你看到了httpd是吧?如果你再不查看这个httpd我就捏死你了啊 😛 。
    apache-er8
    好了,这里定义了对某个路径下的error.log, xxxx, 还有apache日志目录下的access_log的日志处理方式。
    然后postrotate那段看到了吗?整个postrotate翻译成人话就是:执行完rotate动作之后,如果有pid文件的话就发一个USR1信号给pid文件的内容。
    又,postrotate,post这个前缀的意思就是“在xxx之后”,pre的意思是“在xxx之前”。不过大部分情况下,我们会使用after做命名吧 🙂 。
  4. 结论
    现在可以对得上了,apache的重启就是因为logrotate产生的。但为什么要这么干呢?
    如果apache在运行,你把access_log改名为access_log.1的话。如果你天真地以为mv完之后会生成一个新的access_log的话就错了,access_log并没有生成,apache会继续往access_log.1里写日志,直到apache重启之后,apache才会生成一个access_log,并往这个新文件里写日志。所以在rotate之后,要重启一下apache。
    但如果重启apache的时候,如果哪个不要命的家伙在线上正玩着呢,不是一下子就“打不开服务器”了咩。所以apache在收到USR1信号之后呢,主进程就对子进程说,“在接客的姑娘们,现在手上的活忙完了就不要再接客了哟,忙完了就去屎吧。如果没在接客的就马上去屎吧。我会等你们都消失完之后调入新的配置文件,然后你们再按新的配置文件进来接客吧。”这样会比硬生生地restart要来得舒服一点,所以叫graceful restart。

嗯,如果你要问为什么是凌晨三点?去看一下crontab的配置文件就有了:)

Copyright © 2015. All Rights Reserved.

发表评论

电子邮件地址不会被公开。 必填项已用*标注