8f016f25df
- ORM migration: models/ops 重构 - deploy: 标准化 systemd timer/service 部署体系 - MCP server: 5 个只读工具(任务/状态/数据集) - daily check: 数据一致性巡检 - watch: task_watch 后台监控 - kline_daily: 麦蕊优先,时间门禁15:00 - 删除: task_industry_sector, task_sector_features
149 lines
6.0 KiB
Markdown
149 lines
6.0 KiB
Markdown
# market_data_sync
|
||
|
||
A 股市场数据**定时同步与管理**框架。
|
||
|
||
把 `akshare` / `baostock` / 新浪 / 雪球 / 麦蕊智数 等多个数据源接入到 PostgreSQL 库,提供:
|
||
- 后台线程调度器(time-based + interval-based,交易日感知)
|
||
- 多数据源 + 自动降级 + 健康度监控
|
||
- `dataset_registry` 同步状态机(运行中 / 成功 / 失败 / 中断恢复)
|
||
- FastAPI 管理接口(手动触发、状态查询、失败重试)
|
||
- CLI 入口(手动跑任务、查看状态)
|
||
|
||
> 📖 详细架构说明见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
|
||
|
||
## 运行模式
|
||
|
||
项目支持两种互斥的运行模式,由环境变量 `RUNTIME_MODE` 控制:
|
||
|
||
| 模式 | 值 | 适用场景 | 调度方式 |
|
||
|---|---|---|---|
|
||
| **Docker 模式** | `docker` | `docker compose up` 单容器部署 | 进程内 scheduler(uvicorn + daemon thread) |
|
||
| **systemd 模式** | `systemd` | Linux 宿主机长期运行 | systemd timer/service |
|
||
|
||
> ⚠️ 两种模式**不能同时启用**,否则同一个 task 会被两边各触发一次,造成状态机抖动和重复 IO。
|
||
|
||
### Docker 模式
|
||
|
||
```bash
|
||
# 1. 准备环境(首次)
|
||
cp .env.example .env # 编辑 .env 填写真实 PG 凭据 + XUEQIU_TOKEN + MAIRUI_LICENCE
|
||
|
||
# 2. 启动(包含 postgres + market_sync 服务)
|
||
docker compose up -d
|
||
|
||
# 3. 查看日志
|
||
docker compose logs -f market_sync
|
||
|
||
# 4. 手动触发一次任务
|
||
docker compose exec market_sync python -m app.entrypoints.cli sync kline_daily
|
||
```
|
||
|
||
Docker 模式下 `RUNTIME_MODE=docker` 已写在 `deploy/docker/docker-compose.yml` 中,容器内会启动进程内 scheduler 负责所有同步任务。
|
||
|
||
### systemd 模式
|
||
|
||
```bash
|
||
# 1. 准备环境(首次)
|
||
cp .env.example .env # 编辑 .env 填写真实 PG 凭据
|
||
# 并在 .env 中加上 RUNTIME_MODE=systemd
|
||
|
||
# 2. 部署 systemd units
|
||
sudo bash deploy/systemd/deploy.sh
|
||
|
||
# 3. 查看 timer
|
||
systemctl list-timers market-sync*
|
||
|
||
# 4. 查看 worker / 任务日志
|
||
journalctl -u market-sync -f
|
||
journalctl -u market-sync-moneyflow -f
|
||
```
|
||
|
||
systemd 模式下:
|
||
- 所有 14 个 task 都由 systemd timer 触发
|
||
- `market-sync-worker.service` 会被部署脚本自动 **stop / disable / mask**,避免进程内 scheduler 与 systemd timers 重叠
|
||
- 每日 23:00 `market-sync-daily-check.timer` 跑巡检,失败时 POST webhook
|
||
|
||
### 本地开发模式
|
||
|
||
```bash
|
||
# 1. 准备环境(首次)
|
||
cp .env.example .env # 编辑 .env 填写凭据
|
||
chmod +x start.sh
|
||
|
||
# 2. 启动 API + scheduler(默认 docker 行为,等价于本地单进程)
|
||
./start.sh # http://localhost:8100
|
||
|
||
# 3. 常用命令
|
||
./start.sh worker # 仅启动调度器(无 web)
|
||
./start.sh list # 列出所有同步任务
|
||
./start.sh sync kline_daily # 手动触发一次(dataset_id 即可)
|
||
./start.sh status # 查看调度器/数据源/同步任务状态
|
||
./start.sh datasources # 查看数据源健康度
|
||
./start.sh reseed # 重新 seed 默认配置到 config 表
|
||
|
||
# 4. 一键全量同步(首次接入)
|
||
python bin/runall_once.py
|
||
|
||
# 5. 跑测试
|
||
.venv/bin/pytest tests/ -v
|
||
```
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
app/ # 应用源码
|
||
├── core/ # 核心抽象(config / db / sync / scheduler / datasource base)
|
||
├── sources/ # 数据源实现
|
||
├── tasks/ # 同步任务实现(14 个)
|
||
├── api/ # FastAPI 管理接口
|
||
└── entrypoints/ # 进程入口(cli + worker)
|
||
bin/ # 通用脚本(运行入口、CLI、一次性任务)
|
||
config/ # 配置文件、secrets
|
||
deploy/ # 部署相关
|
||
├── docker/ # Dockerfile + docker-compose.yml
|
||
└── systemd/ # systemd units + 部署脚本
|
||
│ ├── units/ # *.service / *.timer
|
||
│ └── deploy.sh # 一键部署脚本
|
||
docs/ # 架构文档
|
||
logs/ # 日志输出
|
||
tests/ # 单元测试
|
||
Dockerfile -> deploy/docker/Dockerfile
|
||
docker-compose.yml -> deploy/docker/docker-compose.yml
|
||
bin/deploy_systemd.sh -> deploy/systemd/deploy.sh
|
||
bin/systemd_deploy.sh -> deploy/systemd/deploy.sh
|
||
```
|
||
|
||
## 内置同步任务
|
||
|
||
| dataset_id | systemd 触发时间 | Docker scheduler 时间 | 说明 |
|
||
|---|---|---|---|
|
||
| `stock_basic` | 工作日 09:00 | 09:00 | 全市场股票基础信息 + 股本 |
|
||
| `kline_index` | 工作日 15:30 | 15:30 | 六大指数日线 |
|
||
| `kline_daily` | 工作日 15:30(runall)| 15:40 | 增量日 K 线(OHLCV,多源交叉) |
|
||
| `kline_5min` | 工作日 15:30(runall)| 16:00 | 增量 5 分钟 K 线 |
|
||
| `market_regime` | 工作日 15:30(runall)| 16:15 | 市场情绪(衍生源) |
|
||
| `share_snapshot` | 工作日 15:30(runall)| 16:20 | 股本快照(雪球) |
|
||
| `mairui_ma_daily` | 工作日 16:30 | 16:30 | 日 K MA5/10/20/60(本地派生) |
|
||
| `mairui_indicators` | 工作日 16:40 | 16:40 | 日 K MACD/KDJ/BOLL(mairui) |
|
||
| `moneyflow` | 工作日 21:35 | 21:35 | 资金流(主力/大/中/小单净额) |
|
||
| `tick_trade` | 工作日 21:05 | 21:05 | 当天逐笔成交(mairui) |
|
||
| `longhubang` | 工作日 22:00 | 22:00 | 龙虎榜(akshare / 东方财富) |
|
||
| `stock_node` | 周六 11:30 | 周六 11:30 | 股票-节点映射(mairui) |
|
||
|
||
## 添加新数据源
|
||
|
||
1. 在 `app/sources/` 新建 `my_source.py`,继承 `DataSource`
|
||
2. 在 `app/core/datasource/registry.py` 的 `build_default_registry()` 注册
|
||
|
||
## 添加新同步任务
|
||
|
||
1. 在 `app/tasks/` 新建 `task_xxx.py`,继承 `SyncTask`,设置 `dataset_id`
|
||
2. 在 `app/tasks/__init__.py` 的 `TASKS` 字典注册
|
||
3. 在 `app/core/sync/registry.py` 的 `SYNC_DEFINITIONS` 加条目
|
||
4. 如果使用 systemd 模式,在 `deploy/systemd/units/` 新增对应的 `.service` 和 `.timer`
|
||
5. 如果使用 Docker 模式,在 `app/core/scheduler/scheduler.py` 的 `DEFAULT_SCHEDULES` 新增调度项
|
||
|
||
## License
|
||
|
||
私有
|