太长不看
- 用云端私有存储搭了一套免费双通道自动备份系统:加密备份 + 明文直传
- 文件变化后自动上传,每小时全量同步兜底
- 机器人支持查目录、翻页、按序号取文件,Windows 服务开机自启
- 完整记录实施思路和踩坑排查,可封装成一键安装包
- 需要准备:Windows 10/11 + Python 3.11+ + 合规的云存储账号
声明:本文为 AI 辅助开发实践记录。代码由 AI 辅助生成,作者负责需求设计、方案选型、测试、部署和排障。文中出现的云服务、机器人、令牌、用户名均为匿名化占位符,请勿直接复制使用;落地时请结合合规的云存储产品和当地法律法规。
1. 我为什么需要一个自动备份系统
我最怕的事,是电脑突然坏了。博客、课件、代码、学习资料全都存在本地硬盘里,坏了就真的什么都没了。U 盘会丢、会坏;传统网盘要么容量小,要么限速,要么收费;而且大多需要手动上传,经常想不起来备份。
其实这个问题,我上一个项目就尝试解决过。当时我做了 Git 自动同步方案,先问了 AI 一个问题:远端仓库大小、单个仓库能存的文件数,到底有什么限制?得到的答案是:空间和单仓库大小都有明确上限。
那时我就意识到,只靠 Git 一个小工具,解决不了所有备份问题。同步博客这种文件少、体积小的场景没什么压力,但一旦要同步课件、学习资料这类又多又大的文件,就很吃力了。Git 项目虽然也能备份,但只适合小文件。我需要探索一种新的备份范式。
我把上面的痛点整理成了明确的需求:
- 容量要大——能装下课件和学习资料
- 速度不能太慢——别像某些网盘一样上传下载都限速
- 要自动——文件一改,自动同步
- 要异地保存——电脑坏了、U 盘丢了,文件还在别处
- 成本要低——个人使用,不想年年交钱
后来我发现,很多即时通讯软件自带“私有频道/私有空间”能力,可以存放大量文件,恰好符合容量大、成本低、跨设备访问的特点。于是我想:能不能用脚本把本地目录自动推送到云端私有空间,再通过机器人随时取文件?这就是这个项目的直接推动力。
2. 最终做成了什么
一套 Windows 上的双通道备份系统:
- 加密通道:文件先本地加密,再分片上传云端,内容不可直接查看
- 明文通道:文件以原始格式上传,可以在客户端直接查看、下载
- 实时同步:目录有变化,约 5~10 秒内自动上传;每小时还有全量同步兜底
- 机器人:发命令查总目录、今日更新,回复序号就能把对应文件发到私聊
- 后台服务:注册三个 Windows 服务,开机自启、崩溃自动重启
- 一键安装包:把整套系统封装成可以复制到其他电脑使用的安装包
电脑自动备份,手机也能直接传文件,两边数据互通。
3. 技术选型思路
| 组件 | 作用 | 为什么选它 |
|---|---|---|
| 云端私有存储服务 | 文件分片、加密、上传 | 容量大、成本低、支持开放接口 |
| PostgreSQL | 保存文件索引、分片、空间信息 | 原生 Windows 服务,稳定直观 |
| 同步工具 | 加密备份的同步 | 支持远程后端,可命令行调用 |
| 直传客户端 | 明文直传和机器人逻辑 | Python 生态成熟,接口灵活 |
| 机器人接口 | 目录检索、取文件 | 官方开放能力,天然跨设备 |
| NSSM | 注册 Windows 服务 | 开机自启、崩溃自动重启 |
选型时主要考虑三件事:
- 为什么选云端私有空间? 免费、容量大、跨设备(电脑和手机都能访问),不依赖本地磁盘。缺点是依赖第三方平台,所以只作为异地副本,本地保留原文件。
- 为什么加密和明文两条通道? 加密备份安全,文件加密后都是乱码,查看必须依赖服务端;一旦丢失密钥或配置文件,数据就成了死数据。明文直传恰好解决这些缺点:可以跨设备直接查看文件,下载恢复不再依赖电脑,但安全性低。所以两个都要:重要资料走加密,日常文件走明文。
- 为什么分片设 500 MB、默认覆盖模式? 分片越大,云端消息条数越少,方便管理;但又不能设得过大。日常备份不需要每次修改都留历史版本,默认覆盖只保留最新版,需要版本历史的目录可以单独开启 version 模式。
4. 系统架构
所有程序都放在用户目录下,加密备份和明文直传两条链路各自独立:
%USERPROFILE%\.backup\ ← 备份系统的"家"
├─ backup.ps1 加密备份服务(同步工具 + 云存储)
├─ rclone.conf 同步工具配置
├─ backup-config.json 备份源、同步间隔、排除规则
├─ logs\ 同步日志
└─ direct\ 明文直传 + 机器人
├─ direct-watch.ps1 明文直传服务
├─ direct_upload.py 上传与机器人核心
├─ direct_config.json 空间、备份源配置
└─ bot_config.json 机器人配置(敏感,不展示)
整套系统分两条备份链路,外加一个检索机器人,跑在三个 Windows 服务上:
本地目录
├─ 加密备份: FileSystemWatcher -> 同步工具 -> 云存储(加密)
└─ 明文直传: FileSystemWatcher -> 直传客户端 -> 云空间(可直接查看)
机器人
├─ /start 开始
├─ /status 查看状态
├─ /today 今日更新
├─ /all 全部目录
├─ 翻页 / 跳页 / 回复序号取文件
└─ 每日更新 + 停止按钮
加密和明文两条链路互相独立,各自有空间、各自的锁和 manifest 日志,互不影响。
5. 实施路线(通用版)
下面只保留通用的实施思路,具体账号、令牌、密钥的获取方式请按你所选云存储服务的官方文档执行。
5.1 第 1 步:准备环境
安装 Python 3.11+,安装时勾选 “Add Python to PATH”,然后验证:
python --version
能输出版本号就成功。
5.2 第 2 步:安装数据库
使用原生 PostgreSQL 服务,而不是 Docker,减少一层依赖,也更方便开机自启。
创建备份服务专用的数据库账号和库,密码使用随机生成的长密码,并妥善保管。
5.3 第 3 步:搭建云端存储服务
部署一个支持文件分片、加密、上传的服务端,配置文件里放占位符:
# 核心配置占位符
data-source = "postgres://用户名:密码@地址:端口/数据库"
jwt-secret = "JWT_SECRET"
encryption-key = "ENCRYPTION_KEY"
必须修改三处:
| 配置项 | 说明 |
|---|---|
| 数据库连接串 | 换成真实密码和端口 |
| JWT 签名密钥 | 换成随机长字符串,不要使用字面量 |
| 加密密钥 | 随机生成,长度建议 32B,丢失后无法解密 |
生成随机密钥的参考命令:
$b = New-Object byte[] 32
[System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($b)
[System.BitConverter]::ToString($b).Replace("-", "")
服务启动后,用三层检查确认正常:
第 1 层:进程正常、端口在听
第 2 层:Web 可访问(返回 200)
第 3 层:数据库连接能查到一行记录
5.4 第 4 步:配置同步工具
普通版同步工具不一定支持云存储后端,必须使用配套版本,并在 rclone.conf 中填写后端配置:
[remote]
type = cloud
api_host = http://127.0.0.1:8080
access_token = PASTE_ACCESS_TOKEN
chunk_size = 500M
upload_concurrency = 4
encrypt_files = true
random_chunk_name = true
channel_id = 0
root_folder_id =
配置完成后,先列一次远端文件,能列出来就说明令牌填对了。
5.5 第 5 步:安装 Python 依赖
python -m pip install --upgrade 依赖包1 依赖包2
依赖包用于直传上传、机器人交互和图片处理,按实际所选 SDK 安装。
5.6 第 6 步:创建两个私有空间
在云服务中创建两个私有空间:
- 一个加密空间,用于加密备份
- 一个明文空间,用于日常直传
把机器人添加进明文空间并设为管理员,方便后续取文件。
5.7 第 7 步:登录并填写令牌
服务端登录后,会返回会话令牌。令牌不要填在网页里,而是填回本地配置文件的 access_token 位置。
⚠️ 这个令牌等同于登录态,别泄露给别人;一旦泄露,请立即在服务端撤销并重新生成。
5.8 第 8 步:注册三个 Windows 服务
使用 NSSM 把三个命令注册为服务:
服务 1:云存储 Web 服务 + API
服务 2:加密备份监听
服务 3:明文直传监听
服务启动后,做一次初始扫描并上传 manifest,然后进入监听循环。
5.9 第 9 步:添加备份目录
分别给加密通道和明文通道添加备份目录,设置前缀、频道/空间和覆盖模式。
6. 验证思路
经过验证,脚本可以自动备份,随后我把两个脚本封装成一个菜单界面。
备份时默认忽略隐藏文件和空文件
- 隐藏目录/隐藏文件默认跳过,例如以
.开头的路径、.log文件和 0 字节文件 - 普通文件正常备份,状态文件会记录每个文件的 size、mtime、message_id
我还在统计脚本里加入了隐藏文件和实际备份文件的数量统计,方便校对。
同时,我在云端空间里加了 manifest.txt 统计文件。manifest 不是由本地备份的,所以不计入本地统计;验证后发现各备份源都能正常自动备份。
然后我在机器人上也做了验证:
/status查看状态/all查看全部目录- 回复序号取文件
- 修改文件后触发自动上传
经过校验,加密备份和明文备份都验证成功。从文件备份、读取,到灾备恢复和异常处理,这套系统都能覆盖;需要加密的重要资料可以走加密通道,同时必须妥善备份密钥。
7. 技术原理
| 技术 | 解决什么问题 | 核心原理 |
|---|---|---|
| FileSystemWatcher | 监听目录变化 | Windows 文件系统事件 |
| Debounce 防抖 | 避免频繁触发上传 | 事件后等待 N 秒再执行 |
| 文件锁 | 防止多个同步同时执行 | 独占打开锁文件 |
| 同步工具 | 加密备份同步 | 对比本地和远端差异 |
| 云存储服务 | 分片、加密、上传 | 调用云端开放接口上传分片 |
| PostgreSQL | 保存文件索引 | 记录文件、分片、空间状态 |
| 直传客户端 | 明文直传 | 客户端库封装开放接口 |
| 状态文件 | 记住已上传文件 | 保存 size、mtime、message_id |
| manifest | 记录目录和日期 | 本地生成日志上传云端 |
| 长轮询 | 机器人接收消息 | 定时拉取更新 |
| 回调按钮 | 机器人交互 | 内联键盘 + 回调数据 |
| NSSM | 开机自启 | 把命令注册成 Windows 服务 |
7.1 文件监听
使用 System.IO.FileSystemWatcher 监听目录,事件包括 Changed、Created、Deleted、Renamed。只监听事件还不够,文件系统事件可能漏掉,所以服务里还会做短间隔轮询兜底。
7.2 防抖
事件触发后不立即同步,而是记录最后变化时间;只有距离最后一次变化超过防抖时间才真正执行,避免频繁小修改反复上传。
7.3 文件锁
两个进程不能同时执行同步或上传,否则会产生重复记录。锁的原理是独占打开锁文件:第二个进程尝试打开时被拒绝,表示另一个同步正在运行。
7.4 手动同步优先级
手动同步时,如果后台正在同步,不能直接杀掉进程,否则可能留下半成品数据库记录。方案是:
- 手动同步创建 priority 文件
- 后台循环发现该文件后,停止下一个任务
- 手动同步等待当前任务完成,然后获取锁执行
- 手动执行完成后删除 priority 文件
7.5 同步原理
同步命令让远端和本地一致,支持保留空目录、并发传输、断点续传。sync 会对比本地和远端差异,只上传变化部分。
7.6 状态文件
状态文件记录每个文件的大小、修改时间、消息 ID。扫描时先对比状态:
- 大小和修改时间一致 → 已上传,跳过
- 不一致或没有记录 → 加入待上传队列
- overwrite 模式 → 更新同一条远端消息
- version 模式 → 保留历史版本
7.7 manifest
manifest 记录目录里的所有文件、更新时间、覆盖时间,上传到云端,方便手动核对本地和远端数量。超过最大体积自动轮替,保留最近若干份。
7.8 机器人交互
机器人通过长轮询接收消息,支持文本命令和内联按钮。目录数据由本地生成,机器人只是查询和取文件的入口。
8. 常见问题排查思路
- 网页端无法登录:多为浏览器缓存、Cookie 或扩展拦截,清理后重试,或换浏览器。
- 数据库服务无法启动:检查端口占用、数据目录权限、服务账号;先看系统事件日志。
- 云端显示文件数比本地多:多为本地已删除但远端仍保留,或手机/手工上传;用 manifest 对比。
- 清空远端后再次同步只上传少量文件:索引和远端不一致,先清索引再重建。
- 同步产生重复记录:锁未生效或并发执行,检查锁文件是否残留。
- 同步工具报 HTTP 500:多为服务端配置、令牌或数据库连接问题,先看服务端日志。
- 机器人按钮没有反应:检查机器人令牌、回调处理和更新偏移量。
- 机器人把文件发错位置:检查发送目标 ID 和私聊判断逻辑。
- 手机上传的文件在目录里看不到:目录只汇总本地文件,远端手工文件需要单独标记。
- 0 字节文件无法上传:默认跳过空文件,这是设计行为。
- bat 双击一闪而过:bat 缺少
pause,或在执行后直接退出;检查编码和换行。 - 后台服务找不到 Python:服务环境变量和普通用户环境变量不是一回事,需要显式设置 Python 路径。
- 会话数据库被锁:另一个进程正在使用会话,等待完成或检查锁残留。
- manifest 每小时都更新:没有判断内容是否变化,加内容签名即可。
- manifest 和日志无限增长:设置最大体积轮替和日志保留天数。
- 同步后端突然失效:多为版本不匹配,升级后必须重新验证后端。
- 加密备份不实时同步:事件监听可能漏事件,用短间隔轮询兜底。
- 手动同步中断后实时同步停止:priority 文件残留导致,超过时间自动清理。
9. 总结
这次项目从最初的模糊想法到最终落地,带给我的收获比预期大得多。回头对照最初列的 5 个需求——容量大、速度够用、文件变化后自动上传、异地保存、低成本——全部达成了。
加密通道保护重要资料,明文通道随时手机取文件,两者互补;再加上和 Git 自动同步项目配合,小文件走 Git、大文件走云端,算是真正解决了我的备份焦虑。
整个过程中,代码由 AI 辅助生成,但需求拆解、方案选型、测试验证、问题定位、优先级裁定、锁机制设计都需要自己判断。即使不手写每一行代码,理解系统逻辑和排障思路依然是核心能力。
这个项目比普通脚本项目难度大得多——日志轮替、冲突管理、密钥生成、格式问题、版本冲突,每一个坑背后都涉及操作系统、网络协议、数据库和并发编程的知识。边做边查、反复测试,最终把理论上可行的方案变成了能稳定运行的系统。
如果你也想搭一套自己的备份系统,可以从环境检查开始,逐步安装、添加目录、测试恢复,最后再交给服务自动运行。遇到问题,优先看服务日志和 manifest 统计,往往比瞎猜更快。
最后提醒两件事:加密密钥丢了,已加密的数据基本等于永久丢失;自己的令牌、配置和会话文件不要公开分享。备份的核心不是“上传了多少”,而是“丢了之后能恢复多少”。祝大家备份无忧。
大家好,这是我托管在 CF 的博客网站:https://dsduyopg-github-io.pages.dev/
欢迎大家访问我的网站,有什么问题,欢迎大家提意见。