数据无价,服务器备份机制是服务器维护的重中之重!利用Dropbox的上传脚本+Monit监控实现服务器每周循环生成备份并上传到 Dropbox 网盘,通过 Shell 脚本实现出现备份失败及时通过邮件通知、自动清理旧的备份数据、禁止在黄金时段执行备份、禁止重复覆盖备份,确保服务器的宝贵数据万无一失!

环境安装

Monit 监控服务

安装没有什么技术难度,本文不再啰嗦,有包管理用包管理安装没包管理用源码编译安装,遇到困难自行Google。

RedHat / CentOS / Fedora

1
# yum install monit

Ubuntu / Debian / Linux Mint

1
$ apt-get install monit

Dropbox 上传脚本

直接使用 Andreafabrizi 写好的现成脚本 Dropbox-Uploader 稍作配置即可使用,配置教程下方提及。

下载 Dropbox 上传脚本

1
2
3
4
# GET 脚本到服务器
curl "https://raw.githubusercontent.com/andreafabrizi/Dropbox-Uploader/master/dropbox_uploader.sh" -o /back/dropbox_uploader.sh
# 赋予执行权限
chmod +x dropbox_uploader.sh

配置 Dropbox 上传脚本

访问 https://www.dropbox.com/developers/apps

创建 APP 程序 (点击Create app)
创建 Dropbox API

创建 API 密钥
创建 API 密钥

运行 dropbox_uploader.sh 按提示输入 Dropbox API 密钥

构建备份脚本

本脚本是基于 Monit 的监控原理来写的,所以最好配合 Monit 来使用(邮件报警功能是由 Monit 实现的)。由于我的服务器没有什么要用得上Mysql数据库的程序所以没写这方面的备份脚本,可直接备份Mysql的数据文件夹是一样的效果。

注意事项

  1. 临时文件夹:’BACK_DATA’ 变量的路径不能在要备份的文件夹内,最好就是设置在系统的 ‘tmp’临时文件夹内
  2. 备份文件夹:需要多少备份多少个目录就添加多少个数组,例:备份两个目录 ‘ folder[0]=”/…” folder[1]=”/…” ‘ 备份三个目录 ‘ folder[0]=”/…” folder[1]=”/…” folder[2]=”/…” ‘ 以此类推
  3. Dropbox的目录: ‘DROPBOX_DIR ‘要设置在子目录,这样设置有个好处就是多个服务器的备份不冲突
  4. 成功备份脚本返回 (0 ) 备份失败脚本返回(1)
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/bin/bash

## 需要备份的文件夹
##########################
#需要备份多少个文件夹就添加几个数组(结尾不带/)
folder[0]="/data"
folder[1]="/etc"

## 参数设置
##########################
dropbox="/back/dropbox_uploader.sh" #上传程序脚本位置
BACK_DATA="/tmp/dropbox_tmp" #临时文件夹(不要放在备份文件夹内)
DROPBOX_DIR=/$(hostname) #上传到Dropbox的目录 $(hostname)=当前主机名
tarconf="--exclude=*.log --exclude=*.pyc" #tar打包压缩额外参数
olddata=2 #删除几周前的备份
uptime=0100 #只能在什么时间之前执行(输入纯数字)
upweek=1 #礼拜几执行(0代表星期天)

## 判断是否能执行
################################
if [ $(date +"%H%M") -gt $uptime ]; then #判断是否在指定运行时间内
echo "INFO: No running time" $uptime #显示不在运行时间
exit 0 #正常退出
fi
if [ $(date +"%w") -ne $upweek ]; then #判断是否在指定运行周天内
echo "INFO: No running week" $upweek #显示不在运行时间
exit 0 #正常退出
fi
result=$($dropbox -q search "_NO."$(date +"%Y")$(date +"%W").tar.gz) #搜索云上本周备份文件
if [ -n "$result" ]; then #判断云上是否有本周备份文件
echo "INFO: Be backups $DROPBOX_DIR${result##*$DROPBOX_DIR}" #显示云上已有本周的备份文件路径
exit 0 #正常退出
fi

## 数据上传
################################
## 建立临时文件夹
if [ ! -d "$BACK_DATA" ]; then
sudo mkdir $BACK_DATA
fi
## 数据上传
sloop=${#folder[@]} #获取数组长度
let sloop-=1; #减1(数组从0开始)
for k in $( seq 0 $sloop ); do #循环压缩上传
tar zcf $BACK_DATA/${folder[$k]##*/}_$(date +"%Y%m%d")_NO.$(date +"%Y")$(date +"%W").tar.gz $tarconf -C ${folder[$k]%/*}/ ${folder[$k]##*/} #压缩数据并生成时间与标识代码
if [ $? != 0 ]; then #压缩失败
echo "Error: Pack" ${folder[$k]##*/}_$(date +"%Y%m%d")_NO.$(date +"%Y")$(date +"%W").tar.gz "Error !" #显示错误
exit 1 #退出代码:1
fi
$dropbox -q upload $BACK_DATA/${folder[$k]##*/}_$(date +"%Y%m%d")_NO.$(date +"%Y")$(date +"%W").tar.gz $DROPBOX_DIR/$(date +%Y-%m-%d)/ #上传数据到当前日期文件夹
if [ $? != 0 ]; then #上传失败
echo "Error: UPload" ${folder[$k]##*/}_$(date +"%Y%m%d")_NO.$(date +"%Y")$(date +"%W").tar.gz "Error !" #显示错误
exit 1 #退出代码:1
fi
done
echo "INFO: Upload data successfully" #成功上传数据

## 旧备份数据清理
################################
#提取星期\年份
wold=$(date +"%W")
yold=$(date +"%Y")
## 生成旧文件标识代码
let wold-=$olddata; #减去olddata
if [ $wold -le 0 ]; then #是负数执行
let yold-=1 #年减一
if [ $wold -lt 0 ]; then #判断是否为负数
let wold+=53 #与53相加
else #不是负数
wold=53 #若不为负数则为最大值53
fi
fi
## 搜索数据、删除数据
result=$($dropbox -q search "_NO.$yold$wold.tar.gz") #根据旧文件标识代码搜索数据
if [ -n "$result" ]; then #根据返回结果不为空执行
result=${result##*$DROPBOX_DIR} #处理返回数据提取第一个$DROPBOX_DIR之前的内容
$dropbox -q delete $DROPBOX_DIR/${result%/*} #删除云数据(文件夹)
echo "INFO: Deletes folder "$DROPBOX_DIR${result%/*} #显示删除的文件夹
else #返回结果为空
echo "INFO: NO OldCode "_NO.$yold$wold #云上没有指定文件标识的旧备份文件
fi

## 删除临时文件夹并退出
################################
rm -R $BACK_DATA
if [ $? != 0 ]; then
echo "Warning: $BACK_DATA Delete failed"
fi
exit 0

Monit 监控脚本

Monit 的强大配置都写完的话就跑题了,这里只写邮件服务器的配置和与本文相关的配置。

邮件服务器配置

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
## 每隔多少秒检测一次(第二行为程序启动后延时多少秒检测):
set daemon 120
with start delay 30

## 设置邮件通知服务器(smtp)
set mailserver smtp.example.com port 443
username "mail@example.com"
password "mailpassword"
using TLSV1
with timeout 30 seconds

## 设置邮件通知暂存地址
set eventqueue
basedir /var/lib/monit/events # 储存地址
slots 10 # 最大储存数量

## 制定报警邮件的格式
set mail-format {
from: Monit <mail@example.com>
subject: $HOST 服务器 $SERVICE 故障:$EVENT
message: 详细故障内容

故障主机: $HOST
故障时间: $DATE
Monit 尝试动作: $ACTION

发生故障的条件

$DESCRIPTION

Monit Server
}

备份脚本监控

1
2
3
4
5
6
7
8
#由于备份的时间较长所以设置为3600秒才超时
check program ServerBack with path /back/serverback timeout 3600 seconds
#每 5(既 120*5 秒)个周期运行一次
every 5 cycles
#判断脚本退出码,若不为0则发送一封报警邮件
if status != 0 then alert
# 360(既 120*360 秒)个周期内只发送一封邮件给 hscbook@example.com
alert hscbook@example.com with reminder on 360 cycles

END

遇到什么问题先 Google+Baidu 后再提问才是优秀的程序员!最后附上脚本原理的流程图 我就是想练练流程图的使用



文章协议: Attribution-NonCommercial-NoDerivatives
文章地址: https://www.hscbook.com/article/linux-backups/
除非注明,本博文章均为原创,转载请以链接形式标明本文地址