跳转至

NFarms 备份机制规范(backup)

文档版本:V1.0 发布日期:2026-09-02 文档性质:流程规范类 关联文档:监控告警与工单流转综合规范(V1.4)、告警变量字段统一规范表(V1.4)、统一告警模板规范(V1.0)


1. 变更说明:移除 NFS,改用阿里云盘

项目 原方案(弃用) 新方案(采用)
备份目标 NFS 挂载共享盘 阿里云盘(OpenAPI token 认证上传)
调度 (未定) 每日 02:00(systemd timer)
备份内容 — 数据库 + 日志
备份后动作 — 清除服务器缓存 → 重启服务器
失败处理 — 告警 + 每 30 分钟重试,至 06:00 仍失败升级 CRITICAL 转人工

移除 NFS 的原因:NFS 共享盘依赖内网挂载点(/mnt/backup 等)与存储节点高可用, 单点故障面大、无法跨地域容灾、令牌化审计缺失;迁移至阿里云盘对象存储后: 备份与业务主机解耦、具备云端冗余与生命周期管理、上传即留痕(可审计)。


2. 备份目标与内容

内容 源路径(服务器) 说明
数据库 /opt/Cy/services/system.d/nfarmsd/(nfarmsd.db 等 SQLite) 先 VACUUM INTO 一致性快照再打包;也可直接打包库文件(备份前短暂只读窗口)
日志 /opt/Cy/logs/**(nginx / backend / middleware / agents / platforms) 含访问日志、模块日志、systemd journal 导出

打包格式:nfarms-backup-<date>.tar.zst(tar + zstd;无 zstd 时 gzip)。 包内包含 MANIFEST.json:backup_id / created_at / source_path / size / sha256 / servers。

变量字段(遵循《告警变量字段统一规范表》备份任务特定变量): ${backup_id} ${job_name} ${backup_type} ${backup_status} ${backup_size} ${source_path} ${target_path} ${backup_time} ${last_success_time} ${error_code}。


3. 调度与执行流(每日 02:00)

systemd timer: nfarms-backup.timer
  OnCalendar=*-*-* 02:00:00
  → 触发 nfarms-backup.service(执行 backup-aliyun.sh run)

执行流(backup-aliyun.sh run):
  [02:00] 开始
    ├─ 1. 上报告警  INFO(2)  backup.start   「备份任务开始」
    ├─ 2. 打包 数据库 + 日志 → /opt/Cy/backups/staging/(本地暂存)
    ├─ 3. 阿里云盘 token 校验/刷新 → 上传(秒传优先)
    ├─ 4. 校验上传(远端 sha256 / size)
    ├─ 5. 上报告警  INFO(2)  backup.done    「备份成功」(含 ${backup_size})
    ├─ 6. 清除服务器缓存(见 §4)
    └─ 7. 上报告警  WARNING→INFO  system.reboot.init「初始化系统告警-关机重启」
       → reboot(重启窗口见 §7 故障转移)

失败路径(任一步骤失败):
  └─ 上报告警 ERROR(4)/HIGH(5)  backup.failed 「备份失败」
     → 30 分钟后重试(backup-aliyun.sh retry 循环)
     → 直至 06:00 仍失败 → 升级 CRITICAL(6) + 停止自动重试 + 转人工工单

窗口约束:备份窗口 02:00–06:00(${backup_window_start} = 02:00); 06:00 后不再自动重试,避免影响白天业务。


4. 备份完成后:清除缓存并重启

4.1 缓存清理清单

缓存 动作 说明
dnf/yum 缓存 dnf clean all 清理软件包缓存
journal 旧日志 journalctl --vacuum-time=7d 保留 7 天系统日志(配合日志备份后清理)
/tmp 临时 find /tmp -type f -mtime +7 -delete 清理 7 天前临时文件
nfarms 临时/转码 /opt/Cy/NFarms/hub/media/.cache 等 按策略清理转码中间产物
docker/容器缓存(如用) docker system prune -f 悬空镜像/构建缓存
pagecache sync && echo 3 > /proc/sys/vm/drop_caches 需 root,谨慎执行

清理动作均在备份成功上传后执行;清理日志写入 /opt/Cy/logs/backend/backup.log。

4.2 重启告警链(按《监控告警与工单流转综合规范》级别定义)

事件 级别 触发时机 模板要点
初始化系统告警(关机) HIGH(5) reboot 前发出 预告重启窗口,含 ${server_name} ${backup_id}
恢复完成初始化告警 INFO(2)/CLOSE(0) 重启完成、服务自检通过后发出 恢复通知模板(§7.3),含 ${recovery_time} ${previous_level} ${recovery_reason}
备份失败告警 ERROR(4)(首次) 任一环节失败 备份失败模板(§7.1),含 ${job_name} ${error_code}
重试后仍失败 HIGH(5)→CRITICAL(6) 06:00 截止仍未成功 升级通知,转人工工单

告警来源(source)统一:nfarmsd.backup(主/从服务器分别为 nfarmsd.backup.primary / nfarmsd.backup.standby,用于双机告警区分)。


5. 备份失败重试策略(30 分钟周期)

02:00  备份开始
02:0x  失败 → 上报告警 backup.failed (ERROR)
02:30  自动重试 … 失败 → 上报告警(频控后 ERROR→HIGH 升级)
03:00 … 05:30 每 30 分钟重试一次
06:00  仍失败 → 上报告警 backup.failed.critical (CRITICAL=6)
       → 停止自动重试,自动生成工单转人工介入(红线:1 小时内同一告警
         在 CLOSE(0)/CRITICAL(6) 间震荡 >3 次自动冻结,见综合规范 §3.1)

实现建议:重试调度由系统级 watchdog(systemd timer 每 30 分钟检查 "本窗口是否已成功"状态文件)或脚本内部循环完成; 避免使用长驻进程,防止与 nfarmsd worker 资源竞争。


6. 阿里云盘 token 备份方案

6.1 认证与令牌

项 值/说明
认证方式 OAuth 2.0:client_id / client_secret + refresh_token 换取 access_token
令牌存储 /opt/Cy/certs/backend/aliyun-pan.json(chmod 600,root:nfarms)
内容 { access_token, refresh_token, expires_in, updated_at, drive_id, root_dir }
刷新 access_token 过期(2h)用 refresh_token 静默刷新并回写文件
敏感处理 token 禁止出现在任何告警/日志/模板(《告警模板规范》§5.3:${token} 禁止)

6.2 上传流程(OpenAPI 要点)

1) 刷新令牌:  POST https://openapi.alipan.com/oauth/access_token
              { grant_type: "refresh_token", refresh_token, client_id, client_secret }
              → access_token(有效期 2h)
2) 建目录:    POST /adrive/v1.0/openFile/create  (/NFarms/backup/<yyyymm>)
3) 秒传:      POST /adrive/v1.0/openFile/create  (upload_type=resumable 前置 sha1 秒传检测)
4) 普通/分片上传: POST /adrive/v1.0/openFile/create + /adrive/v1.0/openFile/uploadPart(大文件)
5) 校验:      对比远端 file.size / 本地 sha256(MANIFEST.json)

备份文件远端布局:/NFarms/backup/YYYYMM/backup-YYYYMMDD-HHMMSS.tar.zst + MANIFEST.json(含源主机、备份内容、sha256,便于恢复与审计)。

6.3 恢复演练

月度(每季度至少一次)执行 backup-aliyun.sh restore <backup_id>: 下载 → 解包 → 在隔离环境校验数据库可打开(PRAGMA integrity_check)与日志可读, 生成《恢复演练报告》归档(对应工单状态机:恢复完成 → 总结 → 关闭)。


7. 双服务器与 VPN 通道规划

每日 02:00 重启会产生服务中断窗口,为此按主/从双服务器划分通道:

角色 职责 VPN 通道
主服务器(当前 123.57.85.171) nfarmsd api/gateway/worker、前端、备份执行 只走 VPN 主通道(nfarmsd gateway WS 9991,办公/机器人/传感器流量)
从服务器(备机) 备通道 + WireGuard 接入、VPN 可视化 备通道(gateway standby)+ WireGuard VPN 可视化(wg 状态/隧道可视化服务)

通道规划要点: 1. 主通道(primary):主服务器 nfarmsd gateway 9991;办公终端默认接入; 2. 备通道(standby):从服务器同构 gateway(9991),主服务器重启窗口内 由 DNS/客户端重连策略切换到备通道(nfvpn 配置可配多 gateway 端点,自动 failover); 3. WireGuard 可视化:从服务器承载 WireGuard 服务端与隧道可视化面板 (console 零信任页可展示 wg 隧道状态); 4. 重启窗口(§4.2):主服务器 reboot 前发出初始化系统告警; 重启完成后发出恢复完成初始化告警,服务自检通过后主通道收回流量。


8. 与既有规范的映射

8.1 告警级别映射(nfos 综合规范 weight ↔ nfarmsd /alerts/report)

nfos 规范级别 weight 备份事件 nfarmsd 内部 level 说明
CRITICAL(严重) 6 06:00 截止仍失败、核心备份丢失 4(紧急) 映射见 §5
HIGH(活跃) 5 初始化系统告警(关机重启)、重试超时 4(紧急)→3 上报 body 注明规范级别
ERROR(错误) 4 备份失败(单次,可重试) 3(错误) —
WARNING(警告) 3 清理缓存告警/重试成功 2(重要) —
INFO(提示) 2 备份开始/成功(仅日志+IM 静默) 1(一般) 不触发人工告警
CLOSE(恢复) 0 恢复完成初始化告警(重启后) 5(恢复) 恢复专用

nfarmsd 告警框架内部等级为 0-5(自研:4=紧急最高、5=恢复); 外部事实标准以 nfos 规范 weight(0-6) 为准,上报 body 中带 "weight": 6 与 alarm_id,由告警中心按 weight 展示。 接口:POST /alerts/report { source, title, body, level, server_addr }。

8.2 变量与模板映射

  • 变量命名严格遵循《告警变量字段统一规范表》:备份专用 ${backup_*} / ${job_*} / ${source_path} / ${target_path} / ${error_code} / ${last_success_time} / ${backup_window_start};
  • 告警模板复用《统一告警模板规范》§7.1(备份失败 CRITICAL)、§7.3(恢复 CLOSE)、 §4.1 邮件结构五模块(告警身份/资源定位/故障详情/工单关联/行动指引);
  • 敏感变量处理:${token}(阿里云盘令牌)、${password} 一律禁止进入通知与日志。

9. 落地物

交付物 位置 说明
备份脚本 scripts/deploy/backup-aliyun.sh run / retry / restore 子命令;含 token 刷新与上传、清缓存、告警上报、重启钩子
定时器 脚本内置 install 子命令 生成 nfarms-backup.{timer,service}(02:00)与 30 分钟 retry 定时
令牌文件 /opt/Cy/certs/backend/aliyun-pan.json chmod 600,仅 root/nfarms 可读
备份暂存 /opt/Cy/backups/staging/ 上传成功即清空
日志 /opt/Cy/logs/backend/backup.log 备份/清理/重启全过程留痕
文档 本文档 + NFarmsd 各模块文档 体系一致

安装:sudo bash scripts/deploy/backup-aliyun.sh install(写 timer + 校验令牌)。 手动触发:sudo bash scripts/deploy/backup-aliyun.sh run。 恢复:sudo bash scripts/deploy/backup-aliyun.sh restore <backup_id>。