文档章节

玩转 Linux 之:由 Nginx log rotation 聊聊 mv 的妙用

大数据之路
 大数据之路
发布于 2013/12/24 01:37
字数 2529
阅读 1.8K
收藏 10

3 月,跳不动了?>>>

1、Nginx 下如何正确的做日志切分

今天发现有个 Nginx 日志 rotation 出来大小是 0,很奇怪,按公司的业务场景来说,这是不可能的。

瞅了下前同事留下来的 rotation 脚本,看到了这么两行,也是他们当时 rotation 的方案:

cp tracklog.ooxx.com.access.log ${log_date_dir}/tracklog.ooxx.com.access.log.${log_name_date}
> tracklog.ooxx.com.access.log

然后这个脚本会由 crontab 每 10min 定时的调度一次,每次都将日志通过 cp 截取出来,放到以时间后缀命名的文件中去,

然后清空当前文件,如此循环反复。

初看没问题,但仔细想想,这里面会存在丢数据的问题:从 cp 到 > 清空文件这段时间

丢失数据的多少会依赖你业务的并发程度、当时机器负载、cp 文件的大小共同决定。

那这个问题怎么解决呢?

由于 Nginx 自身并没有提供日志管理功能,但是它提供了一个简单的 log rotation 机制:

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

下面我来详细解释下上面 4 行代码的含义:

(1)首先我们不是 cp,而是 mv 当前日志成为一个归档文件(最好加上时间后缀),此时文件 access.log 的 inode 并未改变,对于 Linux 进程来说,mv 并没有使文件发生变化,而进程是按 inode 追踪文件的,而不是文件名。(关于这点请看文末的 Refer(1))。所以直到 mv 完成以及 mv 完成后, nginx 进程会一直继续读写 access.log.0 文件(其实是 access.log,不是吗?)。

(2)Nginx 内部定义了 USR1 信号,这个信号和我们所用的 kill -9 信号类似的地方在于,他们都属于 linux 信号的一种,你可以 kill -l 查看全部信号的定义,各个发行版的定义会有些许差异;不同的地方在于,-9 属于系统级别的,而 USR1 属于应用软件级别的,开发者自定义的,至于程序收到 -USR1 信号后会干什么事,开发者自己说了算,这点和 -9 这种系统级别的信号不同。所以在这里,kill -USR1 不会杀死 Nginx 进程,而 Nginx Master 进程收到  -USR1 信号后,会重新打开名为 access.log 的日志文件,由于 access.log 已经不存在了,那么 access.log 会重新建立一个这样的文件,并开始往里读写数据,也就是说读写从 access.log.0 又切回到 access.log 了,这样新的请求日志会被重新开始记录了,而这个过程是没有任何读写中断,数据丢失的。

或者平滑重启/usr/sbin/nginx -c /etc/nginx/nginx.conf -s reload

// 运行 nginx -s reload 命令,就会检查磁盘上的配置文件,并给主进程发送一个SIGHUP信号。

// 一旦主进程接受到一个SIGHUP,它会做两件事:

// (1) 重载配置文件、创建一组新的工作进程,新创建的工作进程立即接受连接、处理网络通信( 采用新的配置环境)。

// (2) 通知旧的工作进程优雅地推出,这些工作进程停止接受新连接。一旦当前处理的HTTP请求结束,工作进程会关闭连接。一旦所有连接关闭,工作进程就会退出。

(3)这句的意思是给一定的时间让上一步的读写切换顺利完成,以便可以进行后续的操作,对归档日志进行处理。比如有可能数据还在 nginx 的 buffer 中,没有及时写入  access.log.0 或是系统负载、IO 很高,没有及时响应切换,此时若强行对归档日志  access.log.0 进行处理,则会有数据丢失的风险。

(4)这句代码就是用户后续对归档日志  access.log.0 进行处理了,你可以 gzip、rsync 等等,随你怎么玩吧。

别看这个 rotation 过程只有 4 句简单的代码,但是它里面涉及的知识还是不少的,很多同学貌似都不理解这段过程究竟发生了什么。希望我的这段解说能让你明白这其中的来龙去脉。

文初提到的问题到这里算是有了一个简单、完美的解决方案,其实你也可以用一些三方的工具来做 log rotation,比如 logrotate,但是我觉得就我的这个按时间切分日志的需求来说,上面的 4 行代码已足够简洁了,不是么?

2、文初的问题:为什么用 mv 而不是 cp 呢?

其实我在文中已有阐述,如果你还没明白,建议读读这篇《理解 linux inode》,简单的说就是 mv 没有改变源文件的任何内容以及 inode 属性,也没有创建新文件,这样也就没有中断 nginx 进程对日志文件的读写,自然就不会有丢数据的风险了。而 cp 的话,是新建了一个目标空文件,然后去往里拷贝数据,这是需要时间的,而且无法保证对一个正在读写的文件拷贝数据的完整性。当你重定向清空源文件的时候,数据就会不同程度的丢失了。so,这里用 mv 而不是 cp,至此我想你也应当明白 cp 与 mv 的区别了。

3、最后的问题:文件对于进程的 WYSIWYG 问题

我现在有个文件 ooxx.log,每十分钟生成一个,同时有个 agent 监控进程每秒扫描一次,一旦文件出现了,立即开始传输(空文件和重复文件不会传输)。

那么现在的问题是:如何保证 agent 传输文件数据的完整性呢?

有如下几种方案:

(1)你可以创建文件锁 file.lock,生成完文件后删除,同时改 agent 源码,检测锁是否存在
(2)agent 中调用 lsof、fuse 等系统级调用检测是否还有文件句柄、文件锁未释放
(3)agent 编程语言的内置 API,比如排它锁或者锁检测机制
(4)先写 .tmp 文件,然后 mv

(5)...

你会选择哪种方案?同时各种方案它们有什么优劣呢?

这个问题就先暂且留作思考题吧~

4、SIGHUP 信号的意义与作用

刚有同学问我 SIGHUP 和 kill -9 的区别,后者属于强杀进程,可能内存中的进程数据还没持久化就结束进程,带来的危害是数据丢失,有点类似 windows 下面通过任务管理器终止进程。下面具体聊聊 SIGHUP 的问题。

The SIGHUP (“hang-up”) signal is used to report that the user's terminal is disconnected, perhaps because a network or telephone connection was broken. 
SIGHUP的含义是连接断开,系统对SIGHUP信号的默认处理是终止收到该信号的进程。所以若程序中没有捕捉该信号(拿 sigaction 或者 signal 函数去注册信号处理器,或者拿 sigprocmask 之类的把信号给屏蔽掉),当收到该信号时,进程就会退出。
初衷是为了在终端挂断时告诉终端控制进程这个事件,而在守护进程中,通常用来重读配置文件。为了避免混淆,更多的情况是使用 SIGUSR1 和 SIGUSR2 来自定义实现不重启、终止进程而重新加载配置,或者其它功能。
因此如果程序中没有捕捉并处理这个信号,系统默认的动作是杀掉进程。大部分 daemon 进程都会捕捉并处理这个信号,重新读入配置文件。其它的程序没有处理,就被杀掉了。
SIGHUP会在以下3种情况下被发送给相应的进程:
1、终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用 & 符号提交的进程)
2、session首进程退出时,该信号被发送到该session中的前台进程组中的每一个进程
3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。

4、kill -1,-1 对应的 signal 是 SIGHUP,SIGHUP对daemon是重新读取配置,对普通进程就是杀掉。一般的守护进程都会在收到这个信号时重新加载配置(本质上由开发者决定),因为 SIGHUP 本来的意义对守信进程没有意义(SIGHUP 是当控制终端失去连接时触发的信号,而守护进程没有控制终端,所以根本用不上)。
具体可以参考 nohup(1)

举例说明:
比如用户修改了 apache 配置文件,想不重起 apache 就让配置生效,可以往 apache 进程发一个 HUP 信号:killall -HUP httpd

或者 inetd 配置文件是 /etc/inetd.conf, 如果想inetd 去重读文件系统的话,可以给它发一个SIGHUP 信号。
再例如, 当你ssh到一台机器, 然后开个vim, 当你关闭这个 ssh 会话的时候 vim 就会收到 SIGHUP 信号,然后 vim 就会被终止。

参考:https://www.freebsd.org/doc/zh_CN/books/handbook/basics-daemons.html

http://httpd.apache.org/docs/2.2/stopping.html

Refer:

1、理解 linux inode

http://hi.baidu.com/leejun_2005/item/7893859e427ec9d91f427182

2、Nginx wiki:Log Rotation

http://wiki.nginx.org/LogRotation

3、How To Configure Logging and Log Rotation in Nginx on an Ubuntu VPS

https://www.digitalocean.com/community/articles/how-to-configure-logging-and-log-rotation-in-nginx-on-an-ubuntu-vps

4、linux 系统监控、诊断工具之 lsof 用法简介

http://my.oschina.net/leejun2005/blog/153584

5、python 在删除文件的时候检测该文件是否被其他线程或者进程占用?

http://segmentfault.com/q/1010000000367133

6、Linux 文件系统的实现

http://segmentfault.com/a/1190000000419225

7、进程间共享inode相互影响简单分析 

http://blog.sina.com.cn/s/blog_e59371cc0102ux75.html

8、被遗忘的Logrotate

http://blogread.cn/it/article/6354?f=wb

9、linux下cp,mv进行动态库覆盖问题分析

http://blogread.cn/it/article/6809?f=wb

10、Rotating MySQL slow logs safely

https://www.percona.com/blog/2013/04/18/rotating-mysql-slow-logs-safely/

© 著作权归作者所有

大数据之路
粉丝 1631
博文 514
码字总数 330865
作品 0
武汉
架构师
私信 提问
加载中

评论(1)

5292401
5292401
保证数据完整性的那几种方案如何选择? 期待有后续... : )
Linux下自动分割Nginx日志文件(二)-----Cronolog

一,简介:cronolog 是一个简单的过滤程序,读取日志文件条目从标准输入和输出的每个条目并写入指定的日志文件的文件名模板和当前的日期和时间。当扩展文件名的变化,目前的文件是关闭,新开...

科技小能手
2017/11/12
0
0
nginx常识(转自本人的csdn)

nginx常用命令 nginx -c /usr/local/nginx/conf/nginx.conf 启动nginx(windows下start nginx); nginx -s quit 停止ngix nginx -s reload 重新载入nginx(当配置信息发生修改时) nginx -s reop......

WinkJie
2019/05/20
27
0
针对中小型网站(3000人左右/15分钟)的服务器架构

针对中小型网站(3000人左右/15分钟)的服务器架构 本文系原创, 转载注明来自: www.hao32.com 本文涉及的服务器构架主要针对3000人左右/15分钟的中小型网站, 多见于discuz!论坛构建的社区等等 ...

zt371
2009/05/06
1.3K
0
linux常用脚本

nginx日志分割脚本 /shell/nginx-log-split.sh #!/bin/bash base_path='/home/wwwlogs' log_path=$(date -d yesterday +"%Y%m") day=$(date -d yesterday +"%d") mkdir -p $basepath/$logpa......

我心中有猛狗
2016/07/04
36
0
2018-3-14 Linux学习笔记

12.10 Nginx访问日志 Nginx访问日志的格式是在主配置文件中定义的. vim /usr/local/nginx/conf/nginx.conf //搜索logformat 日志字段含义: $remoteaddr 客户端IP(公网IP) $httpxforwardedfo...

XiaoluHuang
2019/01/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

mapbox

Mapbox是一个可以跨行业使用的开发平台,我们可以利用它对地图进行创建和定制,以解决地图、数据和空间分析等问题。 Leaflet 轻量 WebGIS 前端类库 Leaflet 是一个为建设移动设备友好的互动地...

东东笔记
7分钟前
16
0
看你有多色游戏案例

看你有多色游戏案例 游戏规则 这款游戏的玩法就是找出所有风格中颜色比较淡的,随着游戏进行后面的方块会越来越多, 这个游戏主要是考验玩家的眼力和注意力, 游戏截图 部分代码 mian.html ...

板栗z丶
36分钟前
23
0
【SpringBoot MQ 系列】RabbitListener 消费基本使用姿势介绍

【MQ 系列】RabbitListener 消费基本使用姿势介绍 之前介绍了 rabbitmq 的消息发送姿势,既然有发送,当然就得有消费者,在 SpringBoot 环境下,消费可以说比较简单了,借助@RabbitListener...

小灰灰Blog
38分钟前
24
0
罗永浩回应做主播带货赚钱还债:主播赚的不是脏钱

  罗永浩的抖音带货生涯,将于 4 月 1 日晚 20 点开始。   虽然老罗对自己带货能力,信心满满,但也有粉丝对其表达了对他直播带货感到失望。   今日,罗永浩发布微博回应称, 不应该感...

水果黄瓜
39分钟前
18
0
二维码传输文件

这是我大概在5,6年前写的东西,当时种种原因,删除了,现在有空闲时间,补发一下。 二维码是现在非常常用的一种信息传播载体,通过智能手机,可以方便快捷的传输小容量信息,是否可以通过二...

豆豆爹地
46分钟前
14
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部