343 lines
13 KiB
Markdown
343 lines
13 KiB
Markdown
# NAS 环境 sanguo_vnpy Web Trader 架构分析
|
||
|
||
## 需求背景
|
||
|
||
- 部署目标:NAS 机器上构建一套 sanguo_vnpy 环境
|
||
- 使用方式:多位将军协同开发,可进行回测、模拟交易、实盘
|
||
- 设计原则:**基础架构保持 vnpy 官方设计不变,只做必要功能扩展**
|
||
- 基础设施:NAS 提供存储和计算,多用户通过 Web Trader 访问
|
||
|
||
---
|
||
|
||
## 基于官方双进程架构在NAS上的适配分析
|
||
|
||
### 当前官方架构图回顾
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 浏览器 / 前端 (各将军本地或通过NAS访问) │
|
||
└─────────────┬───────────────────────────────────────────────┘
|
||
│ HTTPS / WebSocket
|
||
↓
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ NAS机器: Web服务进程 (vnpy_webtrader) │
|
||
│ - FastAPI Web服务器 │
|
||
│ - REST API / WebSocket │
|
||
│ - RPC客户端 │
|
||
└─────────────┬───────────────────────────────────────────────┘
|
||
│ RPC (本地TCP)
|
||
↓
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ NAS机器: 单一共享交易进程 │
|
||
│ - VeighNa Trader 核心 │
|
||
│ - RPC服务端 │
|
||
│ - 所有Gateway连接 │
|
||
│ - 策略运行 │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 潜在问题分析
|
||
|
||
### 问题1:单一共享交易进程无法支持多用户隔离
|
||
|
||
**现状**:官方默认设计是 **单用户单交易进程**
|
||
|
||
在我们NAS场景:
|
||
- 多位将军同时使用同一个交易进程
|
||
- 账户、持仓、策略都混在一起
|
||
- 无法做用户权限隔离
|
||
- 一个用户出错可能影响所有人
|
||
|
||
**风险等级**:🔴 高风险
|
||
|
||
---
|
||
|
||
### 问题2:数据存储路径问题
|
||
|
||
**现状**:vn.py默认数据存在本地路径
|
||
|
||
在我们NAS场景:
|
||
- 数据库文件需要放在NAS共享存储,方便各进程访问
|
||
- 需要规划统一数据目录结构
|
||
- 需要考虑多进程并发访问SQLite的问题(如果用SQLite)
|
||
|
||
**风险等级**:🟡 中风险
|
||
|
||
---
|
||
|
||
### 问题3:进程管理与稳定性
|
||
|
||
**现状**:默认需要手动启停进程
|
||
|
||
在我们NAS场景:
|
||
- 需要后台稳定运行,不能随会话退出而终止
|
||
- 需要崩溃自动重启
|
||
- 需要方便查看日志、排查问题
|
||
- 需要系统级别的进程监控(systemd)
|
||
|
||
**风险等级**:🟡 中风险
|
||
|
||
---
|
||
|
||
### 问题4:网络访问路径
|
||
|
||
**现状**:默认仅本地访问
|
||
|
||
在我们NAS场景:
|
||
- NAS通常在内网,需要外网访问需要做好反向代理
|
||
- WebSocket需要特殊配置支持反向代理
|
||
- 证书问题(HTTPS)
|
||
|
||
**风险等级**:🟢 低风险,配置好即可解决
|
||
|
||
---
|
||
|
||
### 问题5:保持基础架构不变的边界
|
||
|
||
你说"基础架构我不太想改",这里需要明确:
|
||
|
||
| 范围 | 是否属于"基础架构" | 是否需要改 |
|
||
|------|-------------------|-----------|
|
||
| vnpy核心MainEngine/EventEngine/RPC设计 | 是 ✅ | ❌ 不需要改 |
|
||
| vnpy_webtrader的FastAPI+REST+WebSocket设计 | 是 ✅ | ❌ 不需要改 |
|
||
| 多用户进程模型(单进程vs多进程) | 不属于基础架构,是部署架构问题 | ✅ 需要适配 |
|
||
| 数据目录存储规划 | 不属于核心架构,是部署配置问题 | ✅ 需要适配 |
|
||
|
||
---
|
||
|
||
## 不同方案对比
|
||
|
||
### 方案A:保持官方架构,单交易进程 + 单Web进程
|
||
|
||
**架构**:
|
||
```
|
||
NAS → 1个交易进程(RPC服务端) → 1个Web进程 → 所有用户共享
|
||
```
|
||
|
||
**优点**:
|
||
- 完全保持官方基础架构,一点不改
|
||
- 资源占用最小
|
||
|
||
**缺点**:
|
||
- ❌ 无用户隔离,所有操作混在一起
|
||
- ❌ 无法支持每人独立测试策略
|
||
- ❌ 一人出错影响全局
|
||
- ❌ 权限无法控制
|
||
|
||
**适用场景**:只有你一个人用,不适合多用户团队协作
|
||
|
||
**结论**:不推荐,不符合我们多将军协作场景
|
||
|
||
---
|
||
|
||
### 方案B:每个用户独立一对进程(推荐)
|
||
|
||
**架构**:
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ Nginx 反向代理 │
|
||
│ - 根据路径/子域名分发到不同Web进程 │
|
||
└─────────────┬───────────────────────────────────────────┘
|
||
├───────────┬───────────┐
|
||
↓ ↓ ↓
|
||
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||
│ Web-姜维 │ │ Web-张飞 │ │ Web-关羽 │ 每个用户一个Web进程
|
||
└─────┬───┘ └─────┬───┘ └─────┬───┘
|
||
│ │ │
|
||
↓ ↓ ↓
|
||
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||
│交易-姜维 │ │交易-张飞 │ │交易-关羽 │ 每个用户一个交易进程
|
||
└─────────┘ └─────────┘ └─────────┘
|
||
│ │ │
|
||
└────────────┼────────────┘
|
||
↓
|
||
NAS共享存储 (各用户独立数据目录)
|
||
```
|
||
|
||
**优点**:
|
||
- ✅ 用户之间完全隔离,互不影响
|
||
- ✅ 每个人可以自由测试自己的策略,不怕弄挂别人
|
||
- ✅ 数据独立存储,权限清晰
|
||
- ✅ 依然保持官方基础架构不变(每个进程都是标准官方架构)
|
||
- ✅ 可以独立启停,不影响他人
|
||
|
||
**缺点**:
|
||
- ⚡ 资源占用比单进程多,但现在NAS性能足够支撑
|
||
- 需要做简单的进程管理和配置文件生成
|
||
|
||
**结论**:推荐!既保持了官方基础架构,又解决了多用户隔离问题,符合需求。
|
||
|
||
---
|
||
|
||
### 方案C:共享交易进程 + 多Web进程 + 用户级数据隔离
|
||
|
||
**架构**:
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ Nginx 反向代理 │
|
||
└─────────────┬───────────────────────────────────────────┘
|
||
┌─────────┴─────────┐
|
||
↓ ↓
|
||
┌─────────┐ ┌─────────┐
|
||
│ Web-张1 │ │ Web-张2 │ 多Web进程,共享一个交易进程
|
||
└─────┬───┘ └─────┬───┘
|
||
│ │
|
||
└──────────┼───────┘
|
||
↓
|
||
┌───────────────┐
|
||
│ 共享交易进程 │ 单一交易核心,通过用户ID隔离数据
|
||
└───────────────┘
|
||
```
|
||
|
||
**优点**:
|
||
- 比方案B省点资源
|
||
|
||
**缺点**:
|
||
- ❌ 需要修改vnpy核心代码加入用户隔离逻辑(违反"基础架构不想改"原则)
|
||
- ❌ 依然存在干扰风险(一个错误操作可能影响所有用户数据)
|
||
- ❌ 维护复杂度高,难以跟进官方更新
|
||
|
||
**结论**:不推荐,改基础架构得不偿失,省了点资源带来更多风险
|
||
|
||
---
|
||
|
||
## 推荐方案:方案B 详细设计
|
||
|
||
### 目录结构规划(在NAS上)
|
||
|
||
```
|
||
/mnt/nas-volume/sanguo_vnpy/
|
||
├── config/ # 全局配置
|
||
│ ├── nginx/ # Nginx配置(各用户站点配置)
|
||
│ └── systemd/ # systemd单元文件
|
||
├── data/ # 全局共享数据
|
||
│ ├── history/ # 历史行情数据(共享只读)
|
||
│ └── master-db/ # 主数据库(可选)
|
||
└── users/ # 用户目录(每位将军一个)
|
||
├── jiangwei/ # 姜维
|
||
│ ├── data/ # 个人数据
|
||
│ ├── logs/ # 日志
|
||
│ ├── strategies/ # 个人策略
|
||
│ ├── config.json # 进程配置(RPC端口,Web端口等)
|
||
│ ├── start_trading.py # 个人交易进程启动脚本
|
||
│ └── start_web.py # 个人Web进程启动脚本
|
||
├── zhangfei/
|
||
│ └── ...
|
||
└── guanyu/
|
||
└── ...
|
||
```
|
||
|
||
### 端口分配规划
|
||
|
||
约定端口分配规则:
|
||
- 交易RPC请求端口:`2000 + 用户编号 * 10`
|
||
- 交易RPC订阅端口:`2000 + 用户编号 * 10 + 1`
|
||
- Web服务端口:`8000 + 用户编号`
|
||
|
||
| 用户 | 编号 | RPC请求 | RPC订阅 | Web端口 |
|
||
|------|------|---------|---------|---------|
|
||
| 姜维 | 1 | 2010 | 2011 | 8001 |
|
||
| 张飞 | 2 | 2020 | 2021 | 8002 |
|
||
| 关羽 | 3 | 2030 | 2031 | 8003 |
|
||
| 赵云 | 4 | 2040 | 2041 | 8004 |
|
||
| ... | ... | ... | ... | ... |
|
||
|
||
### Nginx 配置示例(按路径分发)
|
||
|
||
```nginx
|
||
server {
|
||
listen 443 ssl;
|
||
server_name nas.yourdomain.com;
|
||
|
||
# SSL证书配置...
|
||
|
||
# 姜维
|
||
location /jiangwei/ {
|
||
proxy_pass http://127.0.0.1:8001/;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
|
||
# WebSocket支持
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection "upgrade";
|
||
}
|
||
|
||
# 张飞
|
||
location /zhangfei/ {
|
||
proxy_pass http://127.0.0.1:8002/;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection "upgrade";
|
||
}
|
||
|
||
# 更多用户...
|
||
}
|
||
```
|
||
|
||
### systemd 进程管理(每个用户一对服务)
|
||
|
||
```
|
||
/etc/systemd/system/
|
||
├── sanguo-trade-jiangwei.service
|
||
├── sanguo-web-jiangwei.service
|
||
├── sanguo-trade-zhangfei.service
|
||
├── sanguo-web-zhangfei.service
|
||
└── ...
|
||
```
|
||
|
||
这样:
|
||
- 开机自动启动
|
||
- 崩溃自动重启
|
||
- 可以独立启停某个用户的进程
|
||
- 日志统一通过journald管理
|
||
|
||
---
|
||
|
||
## 需要改动的地方总结(很少,不改核心架构)
|
||
|
||
| 改动项 | 是否改vnpy核心 | 说明 |
|
||
|--------|--------------|------|
|
||
| 1. 规划目录结构 | ❌ 不改动 | 只是创建目录,不碰代码 |
|
||
| 2. 为每个用户生成启动脚本 | ❌ 不改动 | 只是调用官方API,生成启动文件 |
|
||
| 3. Nginx反向代理配置 | ❌ 不改动 | 纯运维配置 |
|
||
| 4. systemd服务文件 | ❌ 不改动 | 纯运维配置 |
|
||
| 5. 端口分配规则 | ❌ 不改动 | 只是配置 |
|
||
|
||
**结论**:完全符合你的要求 "基础架构我不太想改",我们只是做了部署层的适配,vnpy官方核心架构一点不改。
|
||
|
||
---
|
||
|
||
## 存在的其他风险和应对
|
||
|
||
| 风险 | 应对方案 |
|
||
|------|---------|
|
||
| 总资源不够(CPU/内存) | 设定用户上限,不用的进程可以停掉,使用时再开 |
|
||
| 历史行情数据重复存储 | 全局共享一份历史数据,用户数据目录只做链接 |
|
||
| SQLite并发问题 | 推荐MySQL/PostgreSQL存tick/bar数据,或者每个用户独立SQLite |
|
||
| 实盘账户安全 | 每个用户自己保管APIKey,配置文件权限设为600,只有自己能读 |
|
||
|
||
---
|
||
|
||
## 总结建议
|
||
|
||
1. **遵循官方基础架构**:保持"Web进程 + 交易进程"的双进程模型不变,不修改vnpy核心代码
|
||
2. **多用户隔离方案**:每个用户分配独立一对进程,完全隔离,互不影响
|
||
3. **目录规划**:全局共享数据放公共区,每个用户数据独立存放
|
||
4. **进程管理**:用systemd管理各进程,开机自启,崩溃自动恢复
|
||
5. **访问入口**:用Nginx反向代理,按路径分发,统一入口
|
||
|
||
这个方案完全满足:
|
||
- ✅ 基础架构不改动
|
||
- ✅ 支持多位将军同时协作
|
||
- ✅ 隔离性好,一人出问题不影响全局
|
||
- ✅ 便于运维管理
|
||
- ✅ 支持回测、模拟、实盘
|
||
|
||
你的意见如何?确认这个方向我就开始动手搭建基础目录和配置模板。
|