前言
随着维护服务器的增多,每天一台台检查备份已经不切实际,即使通过email的方式(备份脚本执行完后将备份信息发送到指定邮箱)检查也要耗费不少的时间,每天做这种重复性且繁杂的事情对我们这类懒人来说简直痛不欲生。经过一次惨痛的教训之后,决定做个备份检查(监控)程序。
原理
原理挺简单,本地服务器通过备份检查脚本检查备份文件是否存在,并将检查结果提交到sae的mysql数据库里,最后通过一个web页面将数据统一显示出来。
实例
假设有5台服务器(web1~web5),备份项目有:msyql数据库、mongodb数据库和/data/img的rsync+inotify实时同步,具体的备份信息如下:
备份项目 |
本地备份保存路径及文件名 |
异地备份保存路径及文件名 |
rsync+inotify |
/data/img |
/bk/$hostname/img/* |
mysql |
/data/bk/msyql/mysql_日期.tgz |
/bk/$hostname/mysql/mysql_日期.tgz |
mongodb |
/data/bk/mongodb/mongodb_日期.tgz |
/bk/$hostname/mongodb/mongodb_日期.tgz |
程序文件说明:
文件名 |
功能 |
getdata.php |
用于获取客户端POST过来的数据并将数据提交到mysql数据库 |
bk.sh |
服务器上的备份检查脚本 |
bk.php |
web页面 |
首先到创建数据库:
1 2 3 4 5 6 7 8 9
| CREATE TABLE `bk_monitor` ( `id` smailint NOT NULL auto_increment, `hostname` varchar(20) default NULL, `rsync` tinyint default NULL, `mysql`varchar(20) default NULL, `mongodb` varchar(20) default NULL, `date` timestamp, PRIMARY KEY (`id`) )
|
getdata.php
用于获取客户端POST过来的数据并将数据提交到mysql数据库。
shell脚本中,只要使用curl -d xxx=xxx http://www.cszhi.com/getdata.php, 就可以将数据提交到服务器端的mysql数据库里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| < ?php $posts=$_POST; foreach ($posts as $key => $value) { $posts[$key] = trim(addslashes($value)); } $db="bk_monitor"; $type=$posts['type']; switch ($type) { case 0: $hostname=$posts['hostname']; $rsync=$posts['rsync']; $mysql=$posts['mysql']; $mongodb=$posts['mongodb']; $sql="insert into $db(hostname,rsync,mysql,mongodb) values('$hostname','$rsync','$mysql','$mongodb')"; break; case 1: $hostname=$posts['hostname']; $rsync=$posts['rsync']; $mysql=$posts['mysql']; $mongo=$posts['mongo']; $sql="update $db set rsync='$rsync',mysql='$mysql',mongodb='$mongodb' where hostname='$hostname'"; break; default: exit('error!!!'); } $conn = mysql_connect("localhost","root","aaabbb123","bk_monitor") or die("can't connect mysql:".mysql_error()); mysql_query($sql,$conn) or die("query error:".mysql_error().":".$sql); mysql_close($conn); ?>
|
bk.sh
服务器上的备份检查脚本。脚本有验证异备服务器上的文件是否存在,所以需要先在服务器上设置能ssh无密码登陆到异备服务器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #!/bin/bash #Program: #check the backup file and submit to the sae database #History: #2013/12/31 caishzh #变量初始化 HOSTNAME=$(hostname) TODAY=$(date +%Y%m%d) REMOTEIP="10.35.14.55" #这里是异备服务器的ip地址 TIMESTAMP=$(date +%s) TIMESTAMPFILE="/data/img/tmp/$TIMESTAMP" [ -f "/data/img/tmp" ] || mkdir /data/img/tmp LOG="/var/log/bk.log" URL="http://webshot.sinaapp.com/getdata.php" [ "$1" == 1 ] && TYPE=0 || TYPE=1 #函数:检查本地备份文件和异地备份文件是否存在 function isExistFile() { [ -f $1/$2 ] || { echo 2;echo "$1/$2 doesn't exist...">>$LOG;exit; } #判断远程文件是否存在 if [ $(ssh -o ConnectTimeout=10 $REMOTEIP "test -f $3/$2 && echo true || echo false") == "true" ];then size=$(ssh -o ConnectTimeout=10 $REMOTEIP "ls -lh $3/$2|cut -d' ' -f5") echo "0_$size" else { echo 1;echo "remote file ${REMOTEIP}:$3/$2 doesn't exist...">>$LOG;exit; } fi } echo "=====$(date +'%F %T') start=====" >>$LOG #mysql和mongodb备份文件检查 MYSQBKFILE="$(isExistFile /data/bk/mysql mysql_${TODAY}.tgz /bk/${HOSTNAME}/mysql)" MONGODBBKFILE="$(isExistFile /data/bk/mongodb mongodb_${TODAY}.tgz /bk/${HOSTNAME}/mysql)" #rsync实时同步检查 #在同步目录的tmp目录下,touch一个文件(文件名就是当前时间戳),sleep 5秒后,再判断远程目录是否存在这个文件,存在则rsync同步正常,不存在则异常 #sleep的时间可以根据自己服务器的情况调整 touch $TIMESTAMPFILE sleep 5 if [ $(ssh -o ConnectTimeout=10 $REMOTEIP "test -f /bk/${HOSTNAME}/img/tmp/${TIMESTAMP} && echo true || echo false") != "true" ];then RSYNCBAK=2 echo "rsync error..." >>$LOG fi RSYNCBAK=${RSYNCBAK:=0} #将数据提交至数据库 curl --connect-timeout 10 -d type=${TYPE} -d rsync="${RSYNCBAK}" -d mysql="${MYSQBKFILE}" -d mongodb="${MONGODBBKFILE}" -d hostname="${HOSTNAME}" $URL echo -e "=====$(date +'%F %T') finish=====\n" >>$LOG
|
第一次执行时,脚本后面加个参数1,往数据库里新插入一条数据:
将bk.sh放到crontab,每天早上8点定时运行:
1
| echo "0 8 * * * root sh /root/tool/bk.sh" >>/etc/crontab
|
bk.php web页面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| < !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html;charset=GB2312"/> <title>bk monitor</title> <link rel="stylesheet" href="style.css"> </link></head> <body> <h2>bk monitor</h2> <table border='1'> <tr> <th>id</th> <th>hostname</th> <th>rsync</th> <th>mysql</th> <th>mongodb</th> <th>date</th> </tr> < ?php function status($bkname) { $str=explode("_",$bkname); $status=(int)$str[0]; if ($status==0) { if(empty($str[1])) echo "<td>OK"; else echo "<td>OK $str[1]</td>"; } elseif ($status==1) { echo "<td>WARN</td>"; } elseif($bkname==2) { echo "<td>ERROR</td>"; } else { echo "<td>UNKNOW</td>"; } } $mysql = new SaeMysql(); $sql = "SELECT * FROM bk_monitor"; $data = $mysql->getData( $sql ); foreach($data as $value) { echo "<tr>"; echo "<td>".$value['id']."</td>"; echo "<td>".$value['hostname']."</td>"; status($value['rsync']); status($value['mysql']); status($value['mongodb']); echo "<td>".$value['date']."</td>"; echo "</tr>"; } ?> </table> </body> </html>
|
界面如下:

如果想要显示的界面更加直观漂亮点,可以使用bootstrap做点样式,效果如下:
