# 运维策略与配置

> **最后更新**: 2026-05-14

---

## 部署环境

### 核心脚本

| 脚本 | 用途 | 使用场景 |
|------|------|---------|
| `scripts/deploy/setup-production.sh` | 服务器初始化（仅首次） | 安装 Docker、Node.js、PM2、Nginx |
| `scripts/deploy/deploy.sh` | 部署应用 | 每次更新代码时 |

### UAT vs 生产差异

| 项目 | UAT | 生产 |
|------|-----|------|
| 分支 | `staging` | `production` |
| .env | `setup-env.sh uat` | `setup-env.sh production` |
| 触发方式 | push 到 staging 自动部署 | push 到 production 自动部署 |
| CI 工作流 | `.gitea/workflows/deploy-uat.yml` | `.gitea/workflows/deploy-production.yml` |

部署操作由 deploy-ops skill 执行。

---

## 备份策略

### 备份类型

| 类型 | 频率 | 保留时间 | 触发方式 | 用途 |
|------|------|---------|---------|------|
| 自动备份 | 每天 02:00 | 7 天 | Cron | 日常恢复 |
| 部署前备份 | 每次部署前 | 10 个 | 脚本自动 | 快速回滚 |
| 手动备份 | 按需 | 手动管理 | 手动执行 | 重大操作前 |
| 异地备份 | 每天 03:00 | 30 天 | Cron | 灾难恢复 |

### 3-2-1 原则

| 副本 | 位置 | 更新频率 | 保留时间 | 用途 |
|------|------|---------|---------|------|
| 生产库 | 服务器 | 实时 | — | 运行数据 |
| 本地备份 | `/srv/apps/ffoa/backups/` | 每天 02:00 | 7 天 | 快速回滚 |
| 云端备份 | 阿里云 OSS / AWS S3 | 每天 03:00 | 30 天 | 灾难恢复 |

### 命名规范

```
ffoa_YYYYMMDD_HHMMSS.sql.gz          # 每日自动
pre_deploy_YYYYMMDD_HHMMSS.sql.gz    # 部署前
manual_YYYYMMDD_HHMMSS.sql.gz        # 手动
```

备份和恢复操作由 db-backup skill 执行。

---

## 故障等级与 SLA

| 等级 | 说明 | 响应时间 | 解决时间 |
|------|------|---------|---------|
| **P0** | 系统完全不可用 | 15 分钟 | 2 小时 |
| **P1** | 核心功能不可用 | 30 分钟 | 4 小时 |
| **P2** | 部分功能异常 | 2 小时 | 1 天 |
| **P3** | 性能下降 | 1 天 | 3 天 |

紧急联系人：运维负责人（系统整体）、后端负责人（服务+数据库）、前端负责人（应用+界面）。

故障诊断由 troubleshoot skill 执行。

---

## 监控

### 系统指标阈值

| 指标 | 正常 | 告警 |
|------|------|------|
| CPU | < 70% | > 80% |
| 内存 | < 80% | > 90% |
| 磁盘 | < 80% | > 90% |
| PM2 进程 | online | errored/stopped |
| Docker 容器 | running | exited |

### 健康检查告警

- 连续失败 3 次 → 触发告警
- 连续失败 5 次 → 标记不健康
- 响应时间 > 5s → 慢查询告警

### 健康检查端点

| 端点 | 预期 |
|------|------|
| `http://localhost:<backend_port>/api/v1/health` | HTTP 200 · 进程存活基础检查（不查依赖） |
| `http://localhost:<backend_port>/api/v1/health/detailed` | HTTP 200 全部依赖 up · HTTP 503 任一依赖 down（database / redis / temporal）；body 含完整 `services` 详情 |
| `http://localhost:<frontend_port>` | HTTP 200 |

`/health/detailed` 是 LB / 监控的业务级探针：Redis 或 Temporal 不可用时 backend 返回 503，LB 应自动切流量；body 里 `services.<name>.status = down/up/degraded` 可用于具体告警。详见工单 #295 / #242。

端口参考 [01-server-infrastructure.md](01-server-infrastructure.md)。

---

## 日志位置

| 类型 | 位置 |
|------|------|
| 应用日志 | `pm2 logs` |
| 备份日志 | `/srv/apps/ffoa/logs/backup.log` |
| 云备份日志 | `/srv/apps/ffoa/logs/cloud-backup.log` |
| Nginx 访问 | `/var/log/nginx/access.log` |
| Nginx 错误 | `/var/log/nginx/error.log` |

---

## 长跑后台进程的守护规则

任何需要 **7×24 持续运行**的后台进程（SSH 隧道、消息队列消费者、定时轮询脚本、本地代理、TCP 转发器等），必须满足以下三条，缺一不可：

### 1. 必须有 supervisor，不许 fire-and-forget

| ✅ 允许 | ❌ 禁止 |
|---|---|
| `systemd` unit（带 `Restart=always` 或 `Restart=on-failure`） | `nohup ... &`（裸 `nohup`，死了没人管） |
| `systemd --user` + `loginctl enable-linger`（用户级守护） | `crontab @reboot ... &`（只在开机时跑一次） |
| `autossh -M 0`（SSH 隧道专用） | `disown`、`screen`、`tmux` 长跑（人不在就没人维护） |
| `pm2`（Node 进程） | 容器没配 `restart: unless-stopped` |

特别提醒：**`crontab @reboot` 不是 supervisor**——它只在机器重启时触发，进程死后不会重新拉起。359 天没重启的机器，`@reboot` 等于 0 次自愈。

### 2. 必须能验证"杀掉后自动重建"

提交/部署前必须实测一遍：

```bash
# 找到进程主 PID
pgrep -af <process-name>

# kill 之
pkill -9 -f <process-name>

# 等待守护策略允许的最大延迟（RestartSec / autossh poll interval）
sleep 10

# 验证新进程已起
pgrep -af <process-name>
```

文档里必须写明**自愈时间预期**（如"~3 秒"）。

### 3. 必须有可观测性

至少满足以下两条之一：
- 日志走 **journald** 或集中式日志系统（不允许只写 `nohup.out` / 自定义文件，因为文件可能不轮转、不被监控）
- **health probe + 告警**：外部检查端口/进程/HTTP 健康，连续 N 次失败触发告警

理想情况两条都有。

### 反例（本项目历史踩过）

- **2026-04 ~ 2026-05 SAP 隧道**：跳板机 `crontab @reboot + nohup ssh -R` 模式，开发机隧道 4/13 死、UAT/PROD 5/12 死，用户反馈才发现，开发机已断 1 个月。复盘见 `06-sap-tunnel.md` §3「自愈守护（autossh + systemd --user）」 + `.learnings/2026-05-14-sap-tunnel-recovery-via-mac-bridge.md`。

### 排查工具

| 工具 | 用途 |
|---|---|
| `systemctl --user status <unit>` | 服务状态 |
| `journalctl --user -u <unit> -f` | 实时日志 |
| `pgrep -af <pattern>` | 找运行中的进程 |
| `pm2 list` / `pm2 logs --nostream` | Node 进程 |

---

## 运维任务清单

### 每日
- 检查所有服务状态
- 检查错误日志
- 检查磁盘空间
- 检查备份状态

### 每周
- 清理过期日志
- 检查数据库性能
- 审查安全告警

### 每月
- 备份恢复验证
- 灾难恢复演练
