之前一段時間,發現線上日志服務器總是會突然丟失日志,碰到問題時搞的很被動。聯系運維同學,又總是被往后推(后來看了一下日志歸檔腳本,運維同學寫的bug)。索性自己寫了一個腳本,添加到crontab任務中,替換運維同學的腳本。
線上服務器每天大概產生6000-10000個日志文件(部分級別的日志),每個文件99m。壓縮時考慮到盡可能多保留日志,gzip設置的9,壓縮比最大、但是最慢的壓縮算法。如果以單個進程來慢慢壓縮、按天歸檔,日志較多時,一天都歸不完。所以肯定要多個進程壓縮。
bash中,把任務放到后台運行就可以實現『多進程』。不過,線上服務器不能影響到其它服務運行,必須限制進程個數,所以用了一個令牌池來限制進程數。
#!/bin/bash
date=`date -d '2 days ago' +%Y-%m-%d`
declare -a files
files=`find /data1/error/error-${date}_* -type f`
Npro=10 #並行10個子進程壓縮
Pfifo="/tmp/$$.fifo"
mkfifo $Pfifo # 新建一個fifo類型的文件
exec 6<>$Pfifo # 將fd 6指向該文件
rm -f $Pfifo
for((i=1; i<=$Npro; i++)); do
echo
done >&6 # 在fd 6指向的文件中放置$Npro個回車符,作為令牌
for file in $files
do
read -u6 #從fd 6中讀出減去一個回車符,然后向下執行
#如果fd 6中沒有回車符了,進程阻塞在這兒
{
gzip -9 $file
mv $file.gz /data1/error/$date/
echo >&6 #向fd6加上一個回車符
} & #花括號體內的程序后台運行
done
wait
exec 6>&- #關閉fd6
wait命令表示等待前面的后台任務全部完成后才繼續往下執行。