矮子涛涛的日常 - inotify
type: channel
link: https://lateresonance.com/index.php/tag/inotify/
items: 通过inotify实时转移文件脚本

通过inotify实时转移文件脚本
type: item
date: 2020-08-05T07:12:00+00:00
description: 通过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 --> 文件写入完毕后 --> 移动文件到物理磁盘中这里的话还需要请出另外一个救星，inotifyinotify可以用于监控文件的状态，我们可以利用其监控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验证成功！(个人经验与能力有限，脚本比较挫，如果脚本有更好写法可以互相交流)