有人告诉我,由于日志轮换,我们已设置了(脚本化的)每日重启 apache。令人担心的是,如果在 apache 运行并接受请求时进行轮换,logrotate 可能会丢失访问日志中的一行。
有人能告诉我这是否合理、真实,还是完全胡说八道?
答案1
日志轮换后,您需要重新启动服务器,因为 Apache 会保持打开日志的文件句柄,如果不这样做,它将继续写入旧日志文件。将 USR1 发送给父级(优雅重启)应该可以解决问题。
引用自 2.2 文档:
即使是在中等繁忙的服务器上,日志文件中存储的信息量也非常大。访问日志文件通常每 10,000 个请求就会增长 1 MB 或更多。因此,需要定期轮换日志文件,方法是移动或删除现有日志。这在服务器运行时无法完成,因为只要文件保持打开状态,Apache 就会继续写入旧日志文件。相反,必须在移动或删除日志文件后重新启动服务器,以便它打开新的日志文件。
通过使用优雅重启,可以指示服务器打开新的日志文件,而不会丢失任何现有或待处理的客户端连接。但是,为了实现这一点,服务器必须在完成旧请求的服务时继续写入旧日志文件。因此,在重启后必须等待一段时间才能对日志文件进行任何处理。一种典型的场景是简单地轮换日志并压缩旧日志以节省空间:
mv access_log access_log.old
mv error_log error_log.old
apachectl graceful sleep 600
gzip access_log.old error_log.old
执行日志轮换的另一种方法是使用管道日志,如下一节所述。
答案2
完全可行。取决于你如何停止 Apache。
如果你正在执行夜间 HUP 来让服务器启动新日志,那么你应该没问题。任何笨拙的停止和重新启动以及您自己的操作都是您自己的!
但是,夜间 HUP 期间的任何连接都将丢失,这些下注者必须重新连接。如果他们正在进行大量下载,那就太可惜了!
如果您记录作为请求一部分所提供的字节数,则直到下载完成才会记录连接,因此由于 HUP 而断开的那些连接将会在日志中丢失。
您看过新的 2.2.12 版本吗?
其中一个变化是使“通过 rotatelogs 管道传输”更加强大,这样您就可以将轮换推迟到 rotatelogs 实用程序,并让它从头到尾处理您的日志,而无需执行夜间 HUP。因此,如果您的日志字节可用,就不会断开连接,也不会丢失日志事务。
医生说
轮换发生在此间隔的开始处。例如,如果轮换时间为 3600,则日志文件将在每个小时开始时轮换一次;如果轮换时间为 86400,则日志文件将在每晚午夜轮换一次。
如果你查看 rotatelogs 内部,你就不会明白他们是如何做到这一点的,因为根本没有神奇的数字,直到你发现这一行:
tLogStart = (now / tRotation) * tRotation;
这将使开始时间与当前小时的开始时间(对于 tRotation == 3600)或前一个午夜(对于 tRotation == 86400)对齐。谁知道它会对其他数字做什么,例如 16432?
编辑:我忘了说,我们已经看到了优雅运行不太优雅的问题。具体来说,只是让子进程挂起。这似乎已被承认,因为 v2.2.12 现在有一个新的配置指令 GracefulShutdownTimeout,它指定一个超时时间,在此时间之后,httpd 进程将终止,而不管是否有请求被处理。
高血压
“Avahappy,
答案3
为什么丢失一行会造成这么大的影响?如果这很重要,也许日志需要打印出来绿色条作为备份。
答案4
是的,根据其他答案,问题是 apache 将继续写入它已打开的文件句柄。
我们(和许多其他人)使用cronlog以避免这种情况。在此设置中,apache 将日志传送到 cronolog,并且服务器不需要重新启动/重新加载。