前言

备份最厉害的,应该就是程序员啦!小张对数据有一种恐惧,最常用的就是利用『Github Actions』『本地-Github-Gitee』三端同步,甚至服务器四端同步,建站这么久,还从未想过对站点多端备份,因为认为服务器很稳定,平常只是将站点备份在服务器里方便回滚,直至10月22日晚睡前看博客的时候,发现了站点404,本以为是博客挂了,结果发现是所有的站点、应用都下线了,shell工具也链接失败,而腾讯云控制台却显示开机状态,心里一万匹草泥马慌的一批,和@心流沟通后没找出问题所以重启万能大法了

之后@心流在第二天晚上做了一个服务器备份方案:使用Aligo定时备份服务器文件 | 心流

解决方案

参考文档:foyoux/aligo: 🔥简单、易用、可扩展的阿里云盘 API 接口库🚀 | Github

CV代码:使用Aligo定时备份服务器文件 | 心流

@心流做的是服务器与阿里云盘中同时保留备份文件,但是我的服务器只有40G,站点一共1.3G左右,七份就9G了,寸土寸金啊!结合自己的实际情况修改如下:

  1. 备份文件只存在于阿里云盘中
  2. @心流删除备份文件方案中是通过time模块获取过期时间,拼接『过期日期+文件名字』判断阿里云盘中是否存在该文件,存在就删除。但这样存在一些bug,比如两天一备,保留七天,就巧妙的避开了删除的日子,同时避免服务器再次死机导致某天没有按计划运行那么就永远不会删除,所以我改逻辑为遍历判断阿里云盘中文件时间(从文件名中提取,Aligo中不存在文件信息接口)小于当前时间则删除
import shutil
from aligo import Aligo
import time
import datetime
import os
import zipfile


class VPSBackup:
def __init__(self, Aligo):
'''
初始化 阿里云登录用户
:param Aligo: 阿里云盘
'''
self.ali = Aligo
self.remote_folder = ali.get_folder_by_path ( upload_dir )
self.upload ()
self.delete ()

def compress(self):
'''
将需要备份的目录依次压缩并保存至 tmp 下
'''
for i in range ( 0, len ( compress_name_list ) ):
zip_file = compress_dir + '/' + t + "-" + compress_name_list[ i ]
zip = zipfile.ZipFile ( zip_file, 'w', zipfile.ZIP_DEFLATED )
for root, dirs, files in os.walk ( backup_dir_list[ i ] ): # 遍历统计
for each in files:
if os.path.exists ( root + "/" + each ):
zip.write ( root + "/" + each )
zip.close ()

def getFile(self):
'''
获取阿里云盘指定目录下所有备份文件
:return: zip_file_list 列表
'''
zip_file_list = [ ]
list = ali.get_file_list ( self.remote_folder.file_id ) # 获取网盘根目录文件列表
# 遍历文件列表
for file in list:
tmp = {'file_id': file.file_id, 'file_name': file.name}
zip_file_list.append ( tmp )
return zip_file_list

def upload(self):
'''
将 tmp 下的压缩包上传
'''
self.compress () # 压缩
file_list = os.listdir ( compress_dir ) # 压缩文件夹中的文件列表
# 拼接相对路径
print ( file_list )
for i in range ( 0, len ( file_list ) ):
file_list[ i ] = os.path.join ( compress_dir, file_list[ i ] )
# 批量上传压缩后的文件列表
ali.upload_files ( file_list, parent_file_id=self.remote_folder.file_id )

def delete(self):
'''
删除阿里云盘中过期的压缩包 以及 本地 tmp 临时压缩包
'''
zip_file_list = self.getFile ()
for i in zip_file_list:
if (i[ 'file_name' ][ 0:10 ] < t_be):
ali.move_file_to_trash ( i[ 'file_id' ] )
shutil.rmtree ( compress_dir ) # 删掉 tmp 临时文件夹


if __name__ == '__main__':
'''
依次填写
ali:登录阿里云盘
backup_dir_list:需要备份的文件夹路径
compress_name_list:压缩包命名
upload_dir:阿里云盘上传路径
day:压缩包保留天数
'''
# 登录信息存放在 < 用户家目录 >/.aligo/< name >.json中
# ali = Aligo () # 方式一,扫码登录
# ali = Aligo ( refresh_token='<refresh_token>' ) # 方式二,从 网页控制台->应用 获取 token
ali = Aligo ( email=('1310446718@qq.com', 'haivhisaofwu1920u90du90') ) # 方式三,发送邮箱,邮箱+随机定义一个字符串

# 备份目录路径数组
backup_dir_list = [
'D:\Git repo\新建文件夹\_posts\测试1',
'D:\Git repo\新建文件夹\_posts\测试2'
]

# 压缩包文件名数组与 backup_dir_list 一一对应
compress_name_list = [
'测试1.zip',
'测试2.zip'
]
# 阿里云盘上传路径
upload_dir = 'Alist/Backup'
# 压缩包保存多少天
day = 7

# 临时压缩包路径
try:
os.mkdir ( 'tmp' )
except FileExistsError as e:
e = str ( e )
print ( "error:" + e )
print ( '文件夹重名,请将现有tmp文件夹移除或按任意键继续' )
os.system ( 'pause' )
compress_dir = 'tmp'

t = time.strftime ( "%Y-%m-%d", time.localtime () )
t_be = (datetime.datetime.now () - datetime.timedelta ( days=day - 1 )).strftime ( "%Y-%m-%d" )

back = VPSBackup ( ali )

运行一遍测试代码,无误后做定时:

vim /etc/crontab
2 0 * * * root python3 /home/ubuntu/myself/Alist/VPS Backup.py # 0:02
chmod 777 /home/ubuntu/myself/Alist/VPS Backup.py # 不是root用户需要修改.py文件权限

总结

@心流种草了阿里云盘,速度很nice!比某度好很多,以及alist-org/alist | Github网盘挂载工具,之前『Cloudreve』仅支持本地挂载方式,局限于服务器带宽与容量,但Alist支持多云盘挂载,完美解决『Cloudreve』局限性,也更好的管理备份或文件分享

2001年9月11日,在震惊全球的“9·11事件”中,假如位于美国纽约世界贸易中心的公司都有妥善的备份和容灾方案,那么就不会有事件之后大量公司关门的情况出现,之后的东航、马航事件黑匣子更是起到了关键作用。有『备』无患, DON'T BE AN APRIL FOOL. Be prepared. Back up your files on March 31st