diff --git a/README.md b/README.md index 39a3c05..2547781 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ gate_scout_order/ # git clone 后的根目录(名称可自定) ├── onchain_scout_gate/ # 扫描端 · 行情监控、企微告警、信号转发(默认 :8088) ├── gate_order_executor/ # 执行器 · 接信号、Gate 下单、面板风控(默认 :8090+) ├── 部署说明.md # ★ 完整部署 + 升级前备份清单 +├── 备份恢复说明.md # 手动备份 / 恢复(/opt → /root) ├── CLONE.md └── README.md # 本文件 ``` @@ -58,7 +59,8 @@ cd gate_scout_order ``` - 克隆步骤摘要:[CLONE.md](CLONE.md) -- **完整部署、升级备份、PM2、多执行器、关代理**:[部署说明.md](部署说明.md) +- **完整部署、升级备份、PM2、多执行器、关代理**:[部署说明.md](部署说明.md) +- **手动备份与恢复(`/opt/gate_scout_order` → `/root`)**:[备份恢复说明.md](备份恢复说明.md) --- diff --git a/备份恢复说明.md b/备份恢复说明.md new file mode 100644 index 0000000..507466e --- /dev/null +++ b/备份恢复说明.md @@ -0,0 +1,268 @@ +# gate_scout_order · 手动备份与恢复 + +面向 **Ubuntu 服务器**,项目固定在 `/opt/gate_scout_order`,备份目录在 `/root`。 + +`config.yaml` 与 `runtime/` **不入 Git**。升级、`git pull`、误删目录前,请先执行下方 **一键备份**。 + +--- + +## 路径约定 + +| 用途 | 路径 | +|------|------| +| 项目根目录 | `/opt/gate_scout_order` | +| 扫描端 | `/opt/gate_scout_order/onchain_scout_gate` | +| 执行器 | `/opt/gate_scout_order/gate_order_executor` | +| 备份根目录 | `/root/backup_gate_<日期>_<时间>/` | + +PM2 默认进程名:`onchain-scout`、`gate-order-executor`(若你改过名,恢复命令里请自行替换)。 + +--- + +## 备份内容说明 + +### 必须备份(丢失难恢复) + +| 组件 | 文件 | 说明 | +|------|------|------| +| 扫描端 | `config.yaml` | 企微、auth、proxy、monitor 等 | +| 扫描端 | `runtime/alerts.db` | 历史告警、面板策略参数(SQLite KV) | +| 扫描端 | `runtime/order_executors.json` | 执行器转发列表、总开关、Webhook 密钥 | +| 执行器 | `config.yaml` | Gate API、`webhook_secret`、`dry_run` 等 | +| 执行器 | `runtime/signals.sqlite` | 信号流与每笔下单结果 | +| 执行器 | `runtime/risk_prefs.json` | 面板「最低盈亏比」 | +| 执行器 | `runtime/breakeven_prefs.json` | 移动保本开关 | +| 执行器 | `runtime/breakeven_active.json` | 移动保本运行态 | + +### 可选(排障用,体积较大) + +扫描端 / 执行器 `runtime/*.log`、`runtime/pm2-*.log` — 下方一键脚本 **默认不备份日志**;需要时见 [§5 可选:含日志备份](#5-可选含日志备份)。 + +### 多执行器 + +若除 `gate_order_executor` 外还有 **第二套执行器**(另一目录或 `:8091` 实例),请对该目录 **再执行一次** 备份块,或把路径改后单独打包(见 [§6 多执行器](#6-多执行器))。 + +--- + +## 1. 一键备份(推荐) + +在服务器上 **整段复制执行**(需已安装 `sqlite3`:`sudo apt install -y sqlite3`)。 + +```bash +PROJECT_ROOT=/opt/gate_scout_order +BACKUP_DIR=/root/backup_gate_$(date +%Y%m%d_%H%M%S) +SCOUT="$PROJECT_ROOT/onchain_scout_gate" +EXEC="$PROJECT_ROOT/gate_order_executor" + +mkdir -p "$BACKUP_DIR"/{onchain_scout_gate/runtime,gate_order_executor/runtime} +chmod 700 "$BACKUP_DIR" + +# --- 扫描端 config --- +if [ -f "$SCOUT/config.yaml" ]; then + cp -a "$SCOUT/config.yaml" "$BACKUP_DIR/onchain_scout_gate/" +else + echo "WARN: 缺少 $SCOUT/config.yaml" +fi + +# --- 扫描端 runtime(SQLite 用 .backup,其余 cp)--- +if [ -f "$SCOUT/runtime/alerts.db" ]; then + sqlite3 "$SCOUT/runtime/alerts.db" ".backup '$BACKUP_DIR/onchain_scout_gate/runtime/alerts.db'" +else + echo "WARN: 缺少 alerts.db" +fi +[ -f "$SCOUT/runtime/order_executors.json" ] && \ + cp -a "$SCOUT/runtime/order_executors.json" "$BACKUP_DIR/onchain_scout_gate/runtime/" + +# --- 执行器 config --- +if [ -f "$EXEC/config.yaml" ]; then + cp -a "$EXEC/config.yaml" "$BACKUP_DIR/gate_order_executor/" +else + echo "WARN: 缺少 $EXEC/config.yaml" +fi + +# --- 执行器 runtime --- +if [ -f "$EXEC/runtime/signals.sqlite" ]; then + sqlite3 "$EXEC/runtime/signals.sqlite" ".backup '$BACKUP_DIR/gate_order_executor/runtime/signals.sqlite'" +else + echo "WARN: 缺少 signals.sqlite" +fi +for f in risk_prefs.json breakeven_prefs.json breakeven_active.json; do + [ -f "$EXEC/runtime/$f" ] && cp -a "$EXEC/runtime/$f" "$BACKUP_DIR/gate_order_executor/runtime/" +done + +echo "备份完成: $BACKUP_DIR" +find "$BACKUP_DIR" -type f | sort +ls -la "$BACKUP_DIR"/onchain_scout_gate "$BACKUP_DIR"/gate_order_executor 2>/dev/null || true +``` + +执行成功后记下输出的目录名,例如:`/root/backup_gate_20260517_033012`。 + +--- + +## 2. 查看已有备份 + +```bash +ls -lt /root/backup_gate_* 2>/dev/null | head -20 +``` + +查看最新一份目录路径: + +```bash +ls -dt /root/backup_gate_* 2>/dev/null | head -1 +``` + +--- + +## 3. 一键恢复 + +**恢复会覆盖当前 `config.yaml` 与列出的 runtime 文件。** 建议先做一次 [§1 一键备份](#1-一键备份推荐),再执行恢复。 + +将 `BACKUP_DIR` 改成你要恢复的那次备份路径(整段复制后只改第一行): + +```bash +BACKUP_DIR=/root/backup_gate_20260517_033012 +PROJECT_ROOT=/opt/gate_scout_order +SCOUT="$PROJECT_ROOT/onchain_scout_gate" +EXEC="$PROJECT_ROOT/gate_order_executor" + +if [ ! -d "$BACKUP_DIR" ]; then + echo "ERROR: 备份目录不存在: $BACKUP_DIR" + exit 1 +fi + +pm2 stop onchain-scout gate-order-executor 2>/dev/null || true + +mkdir -p "$SCOUT/runtime" "$EXEC/runtime" + +# 扫描端 +[ -f "$BACKUP_DIR/onchain_scout_gate/config.yaml" ] && \ + cp -a "$BACKUP_DIR/onchain_scout_gate/config.yaml" "$SCOUT/" +[ -f "$BACKUP_DIR/onchain_scout_gate/runtime/alerts.db" ] && \ + cp -a "$BACKUP_DIR/onchain_scout_gate/runtime/alerts.db" "$SCOUT/runtime/" +[ -f "$BACKUP_DIR/onchain_scout_gate/runtime/order_executors.json" ] && \ + cp -a "$BACKUP_DIR/onchain_scout_gate/runtime/order_executors.json" "$SCOUT/runtime/" + +# 执行器 +[ -f "$BACKUP_DIR/gate_order_executor/config.yaml" ] && \ + cp -a "$BACKUP_DIR/gate_order_executor/config.yaml" "$EXEC/" +[ -f "$BACKUP_DIR/gate_order_executor/runtime/signals.sqlite" ] && \ + cp -a "$BACKUP_DIR/gate_order_executor/runtime/signals.sqlite" "$EXEC/runtime/" +for f in risk_prefs.json breakeven_prefs.json breakeven_active.json; do + [ -f "$BACKUP_DIR/gate_order_executor/runtime/$f" ] && \ + cp -a "$BACKUP_DIR/gate_order_executor/runtime/$f" "$EXEC/runtime/" +done + +pm2 restart onchain-scout gate-order-executor 2>/dev/null || \ + (cd "$SCOUT" && pm2 start deploy/ecosystem.config.cjs; cd "$EXEC" && bash deploy/pm2-start.sh) +pm2 save 2>/dev/null || true + +echo "恢复完成,自 $BACKUP_DIR" +pm2 status +``` + +恢复后检查: + +- 扫描端面板 `http://<服务器>:8088` — 策略参数、执行器列表是否正常 +- 执行器面板 `http://<服务器>:8090/dashboard` — 信号流历史是否仍在 + +**注意:** `git pull` 后不要用 `git checkout -- runtime/` 或 `git clean` 清掉业务数据。 + +--- + +## 4. 从「最新一份备份」恢复(可选) + +若你确认 `/root` 下最新目录就是要用的那份,可先取路径再恢复: + +```bash +BACKUP_DIR=$(ls -dt /root/backup_gate_* 2>/dev/null | head -1) +echo "将恢复: $BACKUP_DIR" +read -r -p "确认请输入 yes: " ans +[ "$ans" = "yes" ] || { echo "已取消"; exit 1; } + +PROJECT_ROOT=/opt/gate_scout_order +SCOUT="$PROJECT_ROOT/onchain_scout_gate" +EXEC="$PROJECT_ROOT/gate_order_executor" + +pm2 stop onchain-scout gate-order-executor 2>/dev/null || true +mkdir -p "$SCOUT/runtime" "$EXEC/runtime" + +cp -a "$BACKUP_DIR/onchain_scout_gate/config.yaml" "$SCOUT/" 2>/dev/null || true +cp -a "$BACKUP_DIR/onchain_scout_gate/runtime/"* "$SCOUT/runtime/" 2>/dev/null || true +cp -a "$BACKUP_DIR/gate_order_executor/config.yaml" "$EXEC/" 2>/dev/null || true +cp -a "$BACKUP_DIR/gate_order_executor/runtime/"* "$EXEC/runtime/" 2>/dev/null || true + +pm2 restart onchain-scout gate-order-executor 2>/dev/null || true +pm2 save 2>/dev/null || true +echo "已从 $BACKUP_DIR 恢复" +``` + +--- + +## 5. 可选:含日志备份 + +需要连同日志一起打包时,在 **§1 备份脚本末尾** 追加执行: + +```bash +PROJECT_ROOT=/opt/gate_scout_order +BACKUP_DIR=/root/backup_gate_$(date +%Y%m%d_%H%M%S)_with_logs +SCOUT="$PROJECT_ROOT/onchain_scout_gate" +EXEC="$PROJECT_ROOT/gate_order_executor" + +mkdir -p "$BACKUP_DIR" +chmod 700 "$BACKUP_DIR" +cp -a "$SCOUT/config.yaml" "$BACKUP_DIR/scout_config.yaml" 2>/dev/null || true +cp -a "$EXEC/config.yaml" "$BACKUP_DIR/executor_config.yaml" 2>/dev/null || true +cp -a "$SCOUT/runtime" "$BACKUP_DIR/onchain_scout_gate_runtime" +cp -a "$EXEC/runtime" "$BACKUP_DIR/gate_order_executor_runtime" +echo "含日志备份完成: $BACKUP_DIR" +du -sh "$BACKUP_DIR" +``` + +含日志的目录结构与 §1 不同,恢复时请手动 `cp` 对应子目录,或优先使用 §1 标准结构备份。 + +--- + +## 6. 多执行器 + +第二套执行器若在例如 `/opt/gate_scout_order/gate_order_executor_b`: + +```bash +EXTRA_EXEC=/opt/gate_scout_order/gate_order_executor_b +BACKUP_DIR=/root/backup_gate_$(date +%Y%m%d_%H%M%S)_exec_b +mkdir -p "$BACKUP_DIR/runtime" +chmod 700 "$BACKUP_DIR" +cp -a "$EXTRA_EXEC/config.yaml" "$BACKUP_DIR/" +[ -f "$EXTRA_EXEC/runtime/signals.sqlite" ] && \ + sqlite3 "$EXTRA_EXEC/runtime/signals.sqlite" ".backup '$BACKUP_DIR/runtime/signals.sqlite'" +for f in risk_prefs.json breakeven_prefs.json breakeven_active.json; do + [ -f "$EXTRA_EXEC/runtime/$f" ] && cp -a "$EXTRA_EXEC/runtime/$f" "$BACKUP_DIR/runtime/" +done +echo "第二执行器备份: $BACKUP_DIR" +``` + +--- + +## 7. 建议操作时机 + +| 场景 | 建议 | +|------|------| +| 首次部署稳定运行后 | 立刻备份一份 | +| `git pull` / 改目录 / 重装系统前 | 先备份 | +| 改 `config.yaml` 或面板大批量改策略前 | 先备份 | +| 定期(手动) | 每周或每月一次,保留多份不同日期的目录 | + +可将备份目录同步到另一台机器或对象存储(scp、rsync 等),**不要**把含 API 密钥的备份放到公开网盘。 + +--- + +## 8. 故障速查 + +| 现象 | 可能原因 | +|------|----------| +| 升级后面板策略丢了 | 未恢复 `runtime/alerts.db` | +| 执行器列表空了 | 未恢复 `order_executors.json` | +| 信号流历史没了 | 未恢复 `signals.sqlite` | +| `sqlite3: command not found` | 执行 `sudo apt install -y sqlite3` 后重跑备份 | +| 恢复后 PM2 起不来 | `pm2 logs` 看配置校验;检查端口占用 | + +更多部署与升级说明见 [部署说明.md](部署说明.md)。 diff --git a/部署说明.md b/部署说明.md index fd038a6..d4d8491 100644 --- a/部署说明.md +++ b/部署说明.md @@ -369,6 +369,8 @@ source .venv/bin/activate && pip install -r requirements.txt bash deploy/pm2-restart.sh ``` +日常 **手动** 备份与恢复(路径 `/opt/gate_scout_order` → `/root`):见 **[备份恢复说明.md](备份恢复说明.md)**。 + ### 10.3 定期备份(建议 cron 每周) ```bash