228 lines
7.3 KiB
Markdown
228 lines
7.3 KiB
Markdown
# 生产上线检查清单
|
||
|
||
本文档面向“准备把当前仓库作为生产服务上线”的场景,聚焦发布前检查、上线步骤、回滚和日常守护要求。
|
||
|
||
## 目标
|
||
|
||
上线后的最小可用能力应包括:
|
||
|
||
- 数据库可连接且已完成全部迁移
|
||
- API Server 可稳定返回 `/health`、`/api/v1/models`、`/api/v1/reports/latest`
|
||
- 正式日报可由调度脚本按天产出
|
||
- 失败时可回退、可告警、可恢复
|
||
|
||
## 生产拓扑建议
|
||
|
||
建议采用以下最小拓扑:
|
||
|
||
1. PostgreSQL 16
|
||
2. API Server:`cmd/server/main.go` 构建产物
|
||
3. Nginx:托管 `frontend/dist` 并反向代理 `/api` 与 `/health`
|
||
4. Cron 或 systemd timer:执行 `scripts/run_daily.sh`
|
||
|
||
如果使用容器部署,仓库内 `docker-compose.yml` 可作为单机参考,但正式环境仍建议:
|
||
|
||
- 单独管理数据库持久化与备份
|
||
- 在网关层处理 TLS、限流和访问控制
|
||
- 将密钥注入部署系统,而不是依赖仓库内 `.env`
|
||
|
||
## 发布前硬检查
|
||
|
||
### 基础设施
|
||
|
||
- PostgreSQL 已创建库并验证可连接
|
||
- `DATABASE_URL` 在 API Server、调度脚本、备份脚本所在环境都可用
|
||
- `reports/daily` 及其归档目录所在磁盘有足够空间
|
||
- `/tmp` 不会被过早清理,避免影响每天的流水线日志追踪
|
||
|
||
### 数据与迁移
|
||
|
||
- 已执行 `bash scripts/apply_migration.sh`
|
||
- `daily_report`、`report_runs`、`subscription_plan`、`region_pricing`、`daily_signal_snapshot` 等关键表存在
|
||
- 历史数据回填策略已确认,避免上线首日“空库”
|
||
|
||
### 应用与产物
|
||
|
||
- `go test ./...` 通过(仅覆盖 package 形式的 Go 代码,如 `cmd/server` 与 `internal/...`;其中 API 错误结构与模型主价格排序规则需由这些 package tests 兜底)
|
||
- `bash scripts/test_importers.sh` 通过(覆盖 scripts 层 importer targeted go test matrix)
|
||
- `bash scripts/importer_smoke_gate_test.sh` 通过
|
||
- `bash scripts/pipeline_runtime_alignment_test.sh` 通过
|
||
- `bash scripts/test.sh` 通过(仅覆盖 `fetch_openrouter` focused test)
|
||
- `cd frontend && npm run test -- --run` 通过
|
||
- `cd frontend && npm run build` 通过
|
||
- `go build ./cmd/server` 通过
|
||
- 已确认发布结论不是仅凭 `go test ./...` 得出,而是同时包含 scripts 与 gate 层验证
|
||
|
||
### 调度与日报
|
||
|
||
- 正式调度命令已确定:`bash scripts/run_daily.sh`
|
||
- 手工复跑命令已确定:`bash scripts/run_real_pipeline.sh`
|
||
- 历史补跑命令已确定:`bash scripts/rebuild_historical_report.sh YYYY-MM-DD`
|
||
- 日内价格追踪命令已确定:`bash scripts/run_intraday_price_watch.sh`
|
||
- 日内新闻发现与验证命令已确定:`bash scripts/run_intraday_discovery_watch.sh`
|
||
- `OPENROUTER_API_KEY` 已在正式调度环境可用
|
||
- `FEISHU_WEBHOOK` 已配置或明确不上告警
|
||
- 候选发现所需 search / LLM provider 已配置,缺失时会以前置条件错误失败,不会伪装成“无新闻”
|
||
|
||
|
||
### 安全与访问控制
|
||
|
||
- 密钥未提交入库
|
||
- API 暴露路径已放在网关后,不直接裸露到公网
|
||
- 已补充访问控制、TLS、限流与日志保留策略
|
||
- `scripts/restore.sh` 属于高风险脚本,使用权限已收敛到少数运维成员
|
||
|
||
## 上线门禁命令
|
||
|
||
建议按下面顺序执行:
|
||
|
||
```bash
|
||
bash scripts/verify_pre_phase6.sh
|
||
bash scripts/verify_phase6.sh
|
||
bash healthcheck.sh
|
||
```
|
||
|
||
其中 `verify_phase6.sh` 会额外检查:
|
||
|
||
- 真实采集链路
|
||
- API Server 构建与健康检查
|
||
- `/api/v1/models` 响应时间 `< 500ms`
|
||
- 最近 7 次采集成功率 `>= 95%`
|
||
- 前端测试入口存在
|
||
|
||
|
||
## Phase 6+ 范围定义
|
||
|
||
Phase 6 仍是发布前主门禁;`verify_phase6.sh` 通过即可证明主链路验收闭环成立。
|
||
|
||
Phase 6+ 属于 **治理阶段**,不属于发布门禁本身。它覆盖:
|
||
- review / cron / verifier / backlog / memory 的长期治理
|
||
- release 解释语义、风险老化、状态一致性与噪声收敛
|
||
- 外部 provider 漂移后的 fallback / guard / summary 持续补强
|
||
|
||
因此,Phase 6+ 项目未关闭时,不能反推 Phase 6 主验收失败;反之,Phase 6 已通过,也不代表 Phase 6+ 治理工作已经完成。
|
||
## 上线步骤
|
||
|
||
### 1. 发布前备份
|
||
|
||
```bash
|
||
bash scripts/backup.sh
|
||
```
|
||
|
||
确认:
|
||
|
||
- 备份文件已生成在 `/tmp/llm_hub_backups`
|
||
- 备份文件大小非零
|
||
- 如接入 OSS,远端对象已上传成功
|
||
|
||
### 2. 执行迁移
|
||
|
||
```bash
|
||
bash scripts/apply_migration.sh
|
||
```
|
||
|
||
### 3. 构建与发布 API Server / 前端
|
||
|
||
```bash
|
||
go build -o bin/server ./cmd/server
|
||
cd frontend && npm run build
|
||
```
|
||
|
||
### 4. 部署反向代理
|
||
|
||
确认 Nginx 已正确代理:
|
||
|
||
- `/` -> `frontend/dist`
|
||
- `/api/` -> `app:8080/api/`
|
||
- `/health` -> `app:8080/health`
|
||
|
||
### 5. 手工真实复跑一次
|
||
|
||
```bash
|
||
bash scripts/run_real_pipeline.sh
|
||
```
|
||
|
||
目的:
|
||
|
||
- 验证真实采集、补录、日报生成和写库全链路
|
||
- 确认不会错误覆盖“最新正式日报”语义
|
||
|
||
### 6. 启用正式调度
|
||
|
||
```cron
|
||
0 8 * * * cd /path/to/llm-intelligence && bash scripts/run_daily.sh >> /tmp/llm_hub_cron.log 2>&1
|
||
```
|
||
# 日内价格追踪(推荐)
|
||
0 */4 * * * cd /path/to/llm-intelligence && bash scripts/run_intraday_price_watch.sh >> /tmp/llm_hub_intraday.log 2>&1
|
||
# 日内新闻发现与验证(推荐)
|
||
0 */2 * * * cd /path/to/llm-intelligence && bash scripts/run_intraday_discovery_watch.sh >> /tmp/llm_hub_intraday_discovery.log 2>&1
|
||
|
||
### 7. 线上冒烟
|
||
|
||
```bash
|
||
curl -fsS http://127.0.0.1:8080/health
|
||
curl -fsS http://127.0.0.1:8080/api/v1/models
|
||
curl -fsS http://127.0.0.1:8080/api/v1/reports/latest
|
||
```
|
||
|
||
## 运行中监控基线
|
||
|
||
建议至少监控以下指标:
|
||
|
||
| 指标 | 目标 / 告警线 | 说明 |
|
||
|------|---------------|------|
|
||
| API 健康检查 | `200` | `/health` 必须稳定可达 |
|
||
| `/api/v1/models` 响应时间 | `< 500ms` | Phase 6 验收门槛 |
|
||
| 最近 7 次采集成功率 | `>= 95%` | Phase 6 验收门槛 |
|
||
| 模型总数 | `< 300` 告警 | 来自现有 RUNBOOK 基线 |
|
||
| 今日日报是否生成 | 每天 08:00 后应存在 | 检查 `daily_report` 与产物文件 |
|
||
| 归档是否完整 | Markdown + HTML 均存在 | 检查 `reports/daily/YYYY/MM/` |
|
||
|
||
## 回滚方案
|
||
|
||
### 何时触发回滚
|
||
|
||
- API Server 启动失败或健康检查持续异常
|
||
- 真实流水线连续失败且无法在发布窗口内修复
|
||
- 正式日报生成语义错误,导致“最新正式日报”被污染
|
||
- 迁移导致查询失败或关键表结构异常
|
||
|
||
### 回滚步骤
|
||
|
||
1. 停止正式调度,避免继续写入错误数据
|
||
2. 回滚应用版本或镜像
|
||
3. 如数据已损坏,使用备份恢复:
|
||
|
||
```bash
|
||
bash scripts/restore.sh --force /path/to/backup.sql.gz
|
||
```
|
||
|
||
4. 重新执行迁移到目标版本所需状态
|
||
5. 启动服务后执行:
|
||
|
||
```bash
|
||
bash healthcheck.sh
|
||
curl -fsS http://127.0.0.1:8080/health
|
||
curl -fsS http://127.0.0.1:8080/api/v1/reports/latest
|
||
```
|
||
|
||
## 常见上线遗漏
|
||
|
||
- 只启动 API,没有配置正式日报调度
|
||
- 只写入 `daily_report`,但落盘目录没有写权限
|
||
- 手工复跑后误以为“正式日报已准备好”,但 `is_official_daily=false`
|
||
- 把 API 直接暴露到公网,却没有鉴权或限流
|
||
- 依赖 `.env.local`,但生产机器并不存在该文件
|
||
- 没有先跑 `backup.sh` 就执行高风险恢复或迁移
|
||
|
||
## 建议的发布结论标准
|
||
|
||
满足以下条件后,才建议标记为“可生产上线”:
|
||
|
||
- `verify_pre_phase6.sh` 通过
|
||
- `verify_phase6.sh` 通过
|
||
- 手工真实复跑成功
|
||
- API / 前端冒烟通过
|
||
- 正式调度已配置并完成一次演练
|
||
- 备份与恢复路径已演练至少一次
|