JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

docker中的nginx如何实现日志滚动?

wys521 2024-09-29 22:54:37 精选教程 66 ℃ 0 评论

??日志滚动是一种将软件产生的日志按时间周期性地拆分、保存的方法。它有以下好处:

  • 避免日志文件过大,方便查阅、迁移、备份等操作。
  • 提高软件运行性能,减少系统资源占用。
  • 方便采用时间等条件筛选,可以快速定位问题,便于应用服务故障排查。

对于需要持续稳定运行的应用服务来说,日志滚动是非常必要和有意义的。

?

nginx是非常常用的web服务器。我们可以使用logrotate等工具来定期压缩、删除或备份nginx的日志文件。

那么,如何为docker容器中nginx实现日志滚动呢?

?

nginx日志滚动

首先,看看如何为nginx实现日志滚动?

假设nginx的全局访问日志位于/www/server/nginx/logs/access.log。

$ cat logs/access.log
$ curl http://localhost
……
$ cat logs/access.log 
127.0.0.1 - - [28/Feb/2023:14:45:21 +0800] "GET / HTTP/1.1" 200 1326 "-" "curl/7.29.0"

?

USR1

为了实现日志滚动,nginx官方提供的方法会是向nginx进程发送USR1信号,这样可以让nginx重新打开日志文件。

而且这种方法,并不会重启nginx进程,也就不会打断正常的业务。

于是,nginx日志滚动的大致操作如下:

$ mv access.log access.log.0
$ kill -USR1 `cat master.nginx.pid`
$ sleep 1
$ gzip access.log.0 # do something with access.log.0

?

logrotate

由于手工操作太麻烦,可以使用Linux自带的日志滚动工具logrotate进行管理和自动化操作。

logrotate配置相关路径如下:

  • 配置文件:/etc/logrotate.conf
  • 配置目录: /etc/logrotate.d

我们可以在配置目录/etc/logrotate.d下为nginx创建一个配置文件(例如名为nginx),并进行配置。示例配置内容如下:

/www/server/nginx/logs/*.log {
……
create 640 nginx nginx
sharedscripts
postrotate
[ -f /www/server/nginx/logs/nginx.pid ] && kill -USR1 `cat /www/server/nginx/logs/nginx.pid`
endscript
}
?

仅测试,不实际运行:

# logrotate -d -f /etc/logrotate.d/nginx

手工运行:

# logrotate -f /etc/logrotate.d/nginx

?

运行效果如下:

$ ll
-rw-r--r-- 1 www nginx 87 Feb 28 15:29 access.log
$ curl http://localhost/a
……
$ sudo logrotate -f /etc/logrotate.d/nginx
$ ll
-rw-r----- 1 www nginx 0 Feb 28 15:30 access.log
-rw-r--r-- 1 www nginx 87 Feb 28 15:29 access.log.1
$ curl http://localhost/ab
……
$ sudo logrotate -f /etc/logrotate.d/nginx
$ ll
-rw-r----- 1 www nginx 0 Feb 28 15:30 access.log
-rw-r----- 1 www nginx 87 Feb 28 15:30 access.log.1
-rw-r----- 1 www nginx 99 Feb 28 15:30 access.log.2.gz

?

?

nginx容器日志滚动

由于nginx日志滚动是通过USR1?信号实现的,因此理论上需要在容器内进行。

那么有两种思路:

  • 方法一:在容器内编写脚本或者安装logroate等工具,实现日志滚动。

这种方法需要把脚本或者logrotate工具部署到容器中,而后的操作和上述基本相同,这里就不具体实操了。

  • 方法二:把日志目录映射出来,在宿主机上操作。

重点看看这种方法。


首先想到的思路是在宿主机上执行logrotate,但是通过docker exec 在容器中给nginx发送USR1信号。

创建容器的时候,需要将日志目录映射到宿主机上:

$ sudo docker run -d -p 8080:80 -v /home/lighthouse/test-nginx-docker/html:/usr/share/nginx/html -v /home/lighthouse/test-nginx-docker/logs:/var/log/nginx --name nginx nginx

对应logrotate配置如下:

/home/lighthouse/test-nginx-docker/logs/*.log {
……
create 664 root root
sharedscripts
postrotate
docker exec nginx bash -c "if [ -f /var/run/nginx.pid ] ; then kill -USR1 `docker exec nginx cat /var/run/nginx.pid`; echo 'over'; fi"
endscript
}

一切顺利地话,logrotate运行后就可以在宿主机上完成nginx容器日志的滚动。

?

不幸地是,因为容器中没有kill命令,尝试失败了。

那么就进一步考虑,能否在宿主机上给nginx容器进程发送信号。

docker很贴心地提供了docker kill?命令。

于是,logrotate配置调整为:

/home/lighthouse/test-nginx-docker/logs/*.log {
……
create 664 root root
sharedscripts
postrotate
docker kill nginx -s USR1
endscript
}

运行几次之后的效果如下:

[root@VM-12-10-centos test-nginx-docker]# ll logs
total 40
-rw-rw-r-- 1 101 root 0 Feb 28 21:55 access.log
-rw-rw-r-- 1 101 root 90 Feb 28 21:55 access.log.1
-rw-rw-r-- 1 101 root 101 Feb 28 21:55 access.log.2.gz
-rw-rw-r-- 1 101 root 100 Feb 28 21:50 access.log.3.gz

?

总结

为了让nginx进行日志滚动,我们可以用logrotate工具发送USR1信号的方法实现。

如果是nginx容器,我们也可以进一步地结合docker的数据卷映射和exec/kill等命令来实现。

通过这个过程,不仅可以了解nginx日志滚动的具体方法,也能够加深对docker容器机制的理解。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表