通过inotify实时转移文件脚本

背景

公司研发提了个问题:
为了能解决网络上出现的问题,要求系统需要7x24h开启抓包,以方便日后追溯。
抓包通过tcpdump来执行,总计会留存下2000个,每个50M,总计为100G的cap文件,大致指令如下
tcpdump -Z root -w system.cap -i any -C 50 -W 2000
但由于磁盘性能过慢,每次通过tcpdump抓包保存为文件时都会导致系统丢掉了大量无法及时写入的报文,这样抓下来的包完全没法用,要求我们提出解决方案。

解决思路

由于该环境为线上生产环境,又是虚拟化主机,物理服务器上并没有固态之类的可以给到虚拟机上用(成本考虑,老板不给加),即使能用,目前也不允许我们停下业务来专门为这个需求进行增加配置。

好在Linux非常人性化,默认会挂载一个"tmpfs"在/dev/shm目录下,而这个tmpfs不在硬盘上,而是在内存里,这就是传说中的内存盘(ramdisk)了。在现阶段不能增加设备的情况下,tmpfs完全可以利用起来,作为解决当前io瓶颈的一个方式
但是又有一个不得不面对的问题,系统抓下来的包动辄上百G,但我们的内存一共才20G,而且内存盘存的越多,系统可用内存就会减少,如果放任不管,整个环境都会崩溃。
所以咱们的改一下思路,通过脚本及时转移抓包文件,来处理这个问题。

具体思路如下

系统抓包 --> 临时存放在tmpfs --> 文件写入完毕后 --> 移动文件到物理磁盘中

这里的话还需要请出另外一个救星,inotify
inotify可以用于监控文件的状态,我们可以利用其监控tmpfs内生成的抓包文件,一旦文件执行完写入操作时,就及时将文件转移到物理磁盘上进行存放,这样就万无一失了。

实现方法

安装inotify

我们可以通过epel源来简单安装inotify工具,这里我们选用阿里云的eple源来进行安装

# 已安装wget的同志们可以跳过
yum -y install wget

# 通过wget下载阿里云上的eple源配置文件,这里用的是CentOS 6
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo

# 更新加载eple源元数据
yum makecache 
yum -y update

#已安装启用epel的同志可以忽略上面内容

# 安装inotify工具
yum -y install inotify-tools 

编写脚本

这里我们利用一个简单的脚本,具体实现内容如下:

1.监控目录中文件的处于关闭状态的文件(关闭代表写入完成)
2.当文件执行完写入后立刻通过mv移动到物理磁盘中

这里我们的物理磁盘目录为/home/cap/,称为目的路径
报文存放的目录为/dev/shm/cap/,称为源路径

脚本如下:

#!/bin/bash

src=/dev/shm/cap/
des=/home/cap/


#监控目录下文件关闭状态
/usr/bin/inotifywait -mrq --format '%w%f' -e close ${src} | while read file
do
        test -f ${file} && /bin/mv ${file} ${des}
done

之后保存文件,存为inotify.sh,我们需要为脚本添加执行权限让脚本在后台保持运行

chmod +x /home/shell/inotofy.sh
setsid /home/shell/inotify.sh

(由于我存放脚本的路径为/home/shell/中,其他路径请按需修改目录)

检验

在源路径下创建一个文件

touch /dev/shm/cap/test

检查源路径中的文件

ll /dev/shm/cap
total 0

可以发现创建的文件已经消失,此时我们检查下目的路径

ll /home/cap/
total 0
-rw-r--r--. 1 root root 0 May 21 07:40 test

验证成功!

(个人经验与能力有限,脚本比较挫,如果脚本有更好写法可以互相交流)

标签: inotify, Linux