原先的做法
用一个shell脚本遍历需要拉取的机器和需要拉取天数的日志(两者可配置),通过scp命令将应用服务器上的日志拉取到日志服务器上,然后压缩存盘。再将过期的日期删除
存在的问题
- 两个for循环相当于O(n^2)的复杂度
- 顺序执行这么多的任务没有充分利用其服务器的资源
- 拉取的文件未压缩,导致网络流量浪费
- 任务都混杂在一个文件中,不清晰
- 如果任务的执行时间超过1天,会对定时任务造成影响
想到的解决方法
- 将串行任务执行改成并行任务执行
- 任务分解到不同的文件中,用专门的处理进程处理
- 先压缩后拉取,然后删除掉应用服务器上的压缩文件
前期准备
由于对shell以前只是停留在偶尔用的程度,许多知识都需要现查,因此又去学习了一遍,其中包括shell中多进程任务执行,文件监听处理,以及常用的Linux命令
- Linux多任务执行 (多任务执行|http://www.cnblogs.com/xudong-bupt/p/6079849.html) (多进程并发|http://www.cnblogs.com/stevendes1/p/6725898.html) 我第一个看到的是第一个博客,不过他写的多进程程序里有问题,需要把echo >&6挪到任务执行后面,也就是大括号里面。第二个博客讲了原理,也有代码,很棒。
- 文件监听处理 以前用kafka做日志处理时,记得有一个可以使用tail来创建生产者,因此朝着这方面找了下资料,确实可以这么做
shell function dosth(){} tail -f -n 100 $taskFile | while read name file do read -u6 { dosth $name $file echo >&6 # 当进程结束以后,再向fd6中加上一个回车符 } & done
- 其他 Linux函数调用,scp,gzip,echo等命令看了下他们的man页,做起来更有信心
动手
- 任务分类 目前有两个任务,一是拉取日志,二是删除过期日志,因此使用两个文件队列来分别表示这两个任务
- shell处理 一个用于生产需要消费的数据(crontab使用),一个实现拉取日志,一个实现删除过期日志,拉取日志过程中产生的压缩文件也写到删除过期日志任务队列中,由它来专门处理 具体脚本可见GitHub(shell|https://github.com/SixPenny/Scripts/tree/master/pull-logs)