前后端分离怎么部署(系统架构设计:如何支撑5000+股票的实时分析)

前后端分离怎么部署(系统架构设计:如何支撑5000+股票的实时分析)
系统架构设计:如何支撑5000+股票的实时分析
上一篇我们介绍了整个系统的功能概览,这一篇来聊聊架构设计。一个好的架构,是系统稳定运行的基石。

架构设计的核心挑战

在开始设计之前,我们先明确几个核心挑战:

1. 数据量大

  • 沪深A股 5000+ 只股票

  • 每只股票 5年日K线 ≈ 1200条记录

  • 总数据量:5000 × 1200 = 600万条(仅日K线)

  • 还有分钟K线、财务数据、资金流向...

2. 实时性要求高

  • 行情延迟要控制在 3秒 以内

  • 用户操作要有即时反馈

  • 预警触发要及时推送

3. 计算密集

  • 技术指标计算(MACD/KDJ/RSI)

  • 多条件选股筛选

  • 策略回测模拟

4. 并发访问

  • 多用户同时查看行情

  • 多用户同时执行选股

  • WebSocket长连接维护

️ 整体架构设计

基于以上挑战,我设计了如下分层架构:

┌─────────────────────────────────────────────────────────────────────┐
│ 用户层(Client Layer) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ PC Web端 │ │ 移动端 App │ │ Tablet端 │ │
│ │ (Vue3 + AntD) │ │ (Vue3 + Vant) │ │ (响应式布局) │ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │ │
│ └──────────────────────┼───────────────────────┘ │
│ │ │
└──────────────────────────────────┼─────────────────────────────────┘

HTTP/HTTPS + WebSocket

┌──────────────────────────────────┼─────────────────────────────────┐
│ 接入层(Gateway Layer) │
├──────────────────────────────────┼─────────────────────────────────┤
│ │ │
│ ┌────────▼────────┐ │
│ │ Nginx 反向代理 │ │
│ │ 负载均衡 + SSL │ │
│ └────────┬────────┘ │
│ │ │
└──────────────────────────────────┼─────────────────────────────────┘

┌──────────────────────────────────┼─────────────────────────────────┐
│ 应用层(Application Layer) │
├──────────────────────────────────┼─────────────────────────────────┤
│ │ │
│ ┌───────────────────────────────▼───────────────────────────┐ │
│ │ FastAPI 应用服务(Python) │ │
│ ├─────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 行情模块 │ │ 分析模块 │ │ 策略模块 │ │ 预警模块 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │用户管理 │ │数据导出 │ │WebSocket │ │API限流 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘

┌──────────────────────────┼──────────────────────────┐
│ │ │
┌───────▼───────┐ ┌─────────▼────────┐ ┌─────────▼─────────┐
│ 业务逻辑层 │ │ 数据处理层 │ │ 任务调度层 │
│ (Service) │ │ (Data Process) │ │ (Celery) │
├───────────────┤ ├──────────────────┤ ├───────────────────┤
│ │ │ │ │ │
│ ┌───────────┐ │ │ ┌──────────────┐ │ │ ┌───────────────┐ │
│ │行情服务 │ │ │ │数据采集服务 │ │ │ │数据更新任务 │ │
│ │分析服务 │ │◄───────┤ │清洗转换服务 │ │◄─────┤ │回测任务 │ │
│ │选股服务 │ │ │ │指标计算服务 │ │ │ │预警监控任务 │ │
│ │回测服务 │ │ │ └──────────────┘ │ │ │定时任务 │ │
│ │预警服务 │ │ │ │ │ └───────────────┘ │
│ └───────────┘ │ │ ┌──────────────┐ │ │ │
│ │ │ │外部数据接口 │ │ │ ┌───────────────┐ │
│ │ │ │ - Tushare │ │ │ │Celery Beat │ │
│ │ │ │ - AKShare │ │ │ │(定时调度器) │ │
│ │ │ └──────────────┘ │ │ └───────────────┘ │
└───────────────┘ └──────────────────┘ └───────────────────┘
│ │ │
└──────────────────────────┼──────────────────────────┘

┌──────────────────────────────────┼─────────────────────────────────┐
│ 数据层(Data Layer) │
├──────────────────────────────────┼─────────────────────────────────┤
│ │ │
│ ┌─────────────────────┐ ┌─────▼──────────┐ ┌────────────────┐ │
│ │ PostgreSQL │ │ Redis │ │ 文件存储 │ │
│ │ (关系型数据库) │ │ (缓存+队列) │ │ (导出文件) │ │
│ ├─────────────────────┤ ├────────────────┤ ├────────────────┤ │
│ │ - 用户数据 │ │ - 行情缓存 │ │ - Excel导出 │ │
│ │ - 股票基础信息 │ │ - 会话管理 │ │ - 回测报告 │ │
│ │ - 财务数据 │ │ - 任务队列 │ │ - 日志文件 │ │
│ │ - 策略配置 │ │ - 计算结果缓存 │ │ │ │
│ │ - 预警配置 │ │ - WebSocket会话│ │ │ │
│ │ - 日K线数据 │ │ │ │ │ │
│ └─────────────────────┘ └────────────────┘ └────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘

各层职责详解

1️⃣ 用户层(Client Layer)

技术选型:Vue 3 + TypeScript + Ant Design Vue

// 前端项目结构
frontend/
├── src/
│ ├── views/ # 页面视图
│ │ ├── market/ # 行情模块
│ │ ├── analysis/ # 分析模块
│ │ ├── strategy/ # 策略模块
│ │ └── alert/ # 预警模块
│ ├── components/ # 通用组件
│ │ ├── charts/ # 图表组件(K线图等)
│ │ └── common/ # 公共组件
│ ├── stores/ # Pinia状态管理
│ ├── api/ # API接口封装
│ └── utils/ # 工具函数

为什么选择 Vue 3?

特性

优势

Composition API

逻辑复用更方便,代码组织更清晰

响应式系统

自动追踪依赖,数据变化自动更新UI

TypeScript支持

类型安全,IDE提示友好

生态丰富

Ant Design Vue、ECharts等组件库成熟

2️⃣ 接入层(Gateway Layer)

技术选型:Nginx

# nginx.conf 核心配置
upstream backend {
server backend:8000;
}

server {
listen 80;
server_name localhost;

# 前端静态资源
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}

# API代理
location /api/ {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# WebSocket代理
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

Nginx的作用:

  • 反向代理:统一入口,隐藏后端服务

  • 负载均衡:支持多实例部署

  • 静态资源服务:高效分发前端文件

  • SSL终结:HTTPS加密

3️⃣ 应用层(Application Layer)

技术选型:FastAPI

# 后端项目结构
backend/
├── app/
│ ├── api/v1/ # API路由
│ │ ├── market.py # 行情接口
│ │ ├── capital_flow_selector.py # 资金流向选股
│ │ ├── screener.py # 选股接口
│ │ ├── backtest.py # 回测接口
│ │ └── alert.py # 预警接口
│ ├── services/ # 业务逻辑
│ │ ├── capital_flow_selector.py
│ │ ├── momentum_stock_selector.py
│ │ └── backtest.py
│ ├── models/ # 数据模型
│ ├── core/ # 核心配置
│ └── websocket/ # WebSocket处理

为什么选择 FastAPI?

# FastAPI 示例:自动生成API文档
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI(title="A股分析系统API", version="1.0.0")

classStockQuery(BaseModel):
stock_code: str
start_date: str
end_date: str

@app.post("/api/v1/market/kline")
asyncdefget_kline(query: StockQuery):
"""
获取K线数据

- **stock_code**: 股票代码,如 000001.SZ
- **start_date**: 开始日期,格式 YYYYMMDD
- **end_date**: 结束日期,格式 YYYYMMDD
"""
# 业务逻辑...
return {"data": [...]}

特性

优势

异步支持

原生async/await,高并发性能好

自动文档

Swagger UI自动生成,方便调试

类型校验

Pydantic自动校验请求参数

WebSocket

原生支持,无需额外插件

4️⃣ 数据层(Data Layer)

PostgreSQL - 主数据库

-- 核心表结构示例
CREATETABLE stock_daily (
idSERIAL PRIMARY KEY,
stock_code VARCHAR(20) NOT,
trade_date DATENOT,
openDECIMAL(10,2),
highDECIMAL(10,2),
lowDECIMAL(10,2),
closeDECIMAL(10,2),
volume BIGINT,
amount DECIMAL(20,2),
turnover_rate DECIMAL(10,4),
pe_ratio DECIMAL(10,2),
pb_ratio DECIMAL(10,2),
total_mv DECIMAL(20,2),
circ_mv DECIMAL(20,2),
created_at TIMESTAMPDEFAULTCURRENT_TIMESTAMP
);

-- 关键索引:加速查询
CREATEINDEX idx_stock_date ON stock_daily(stock_code, trade_date DESC);
CREATEINDEX idx_trade_date ON stock_daily(trade_date);

Redis - 缓存层

# 缓存策略示例
import redis
import json

redis_client = redis.Redis(host='localhost', port=6379, db=0)

defget_realtime_quote(stock_code: str):
"""获取实时行情(带缓存)"""
cache_key = f"quote:{stock_code}"

# 1. 先查缓存
cached = redis_client.get(cache_key)
if cached:
return json.loads(cached)

# 2. 缓存未命中,查数据源
data = fetch_from_tushare(stock_code)

# 3. 写入缓存,3秒过期
redis_client.setex(cache_key, 3, json.dumps(data))

return data

数据流设计

实时行情数据流

┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Tushare │────▶│ Celery │────▶│ Redis │────▶│ WebSocket│
│ 数据源 │ │ 定时任务 │ │ 缓存 │ │ 推送 │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
│ │
│ ▼
│ ┌──────────┐
└───────────────────────────▶│ 前端 │
写入PostgreSQL持久化 │ 展示 │
└──────────┘

流程说明:

  1. Celery定时任务每3秒从Tushare拉取最新行情

  2. 数据写入Redis缓存(3秒过期)

  3. 同时写入PostgreSQL持久化存储

  4. WebSocket服务监听Redis变化,推送给订阅用户

  5. 前端实时更新UI

选股请求数据流

┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 前端 │────▶│ FastAPI │────▶│ Service │────▶│PostgreSQL│
│ 请求 │ │ API │ │ 业务逻辑 │ │ 查询 │
└──────────┘ └──────────┘ └──────────┘ └──────────┘


┌──────────┐
│ Redis │
│ 结果缓存 │
└──────────┘

WebSocket实时推送架构

# WebSocket连接管理器
classConnectionManager:
def__init__(self):
# 连接池:{user_id: {websocket1, websocket2}}
self.active_connections: Dict[str, Set[WebSocket]] = {}
# 订阅关系:{stock_code: {user_id1, user_id2}}
self.subscriptions: Dict[str, Set[str]] = {}

asyncdefconnect(self, websocket: WebSocket, user_id: str):
"""用户连接"""
await websocket.accept
if user_id notin self.active_connections:
self.active_connections[user_id] = set
self.active_connections[user_id].add(websocket)

asyncdefsubscribe(self, user_id: str, stock_codes: list):
"""订阅股票"""
for code in stock_codes:
if code notin self.subscriptions:
self.subscriptions[code] = set
self.subscriptions[code].add(user_id)

asyncdefbroadcast_quote(self, stock_code: str, data: dict):
"""推送行情"""
if stock_code in self.subscriptions:
for user_id in self.subscriptions[stock_code]:
for ws in self.active_connections.get(user_id, []):
await ws.send_json({
"type": "quote",
"code": stock_code,
"data": data
})

架构图:

数据源更新


┌────────────┐
│ 数据采集 │ ◄────── Celery定时任务(每3秒)
└─────┬──────┘


┌────────────┐
│ Redis发布 │ ────── Pub/Sub模式
└─────┬──────┘


┌────────────────────┐
│ WebSocket Server │
│ (FastAPI) │
├────────────────────┤
│ 连接管理器 │
│ - 用户连接池 │
│ - 订阅关系维护 │
│ - 心跳检测 │
└─────┬──────────────┘

├──────┬──────┬──────┐
│ │ │ │
▼ ▼ ▼ ▼
[User1] [User2] [User3] [User N]
│ │ │ │
订阅: 订阅: 订阅: 订阅:
600519 000001 601318 全市场
000858 600036

⚡ 性能优化策略

1. 数据库查询优化

# ❌ 错误示例:N+1查询问题
for code in stock_codes:
data = db.query(StockDaily).filter(
StockDaily.stock_code == code
).all

# ✅ 正确示例:批量查询
data = db.query(StockDaily).filter(
StockDaily.stock_code.in_(stock_codes),
StockDaily.trade_date == date
).all

2. 缓存策略

数据类型

缓存时间

说明

实时行情

3秒

保证实时性

日K线

1天

收盘后不变

股票列表

1小时

变化频率低

选股结果

5分钟

相同条件复用

3. 异步任务

# 耗时操作放入Celery异步执行
@celery_app.task
defrun_backtest(strategy_id: str, params: dict):
"""异步执行回测任务"""
# 1. 加载历史数据
# 2. 执行策略回测
# 3. 计算收益指标
# 4. 保存结果
return result

项目目录结构

trading_system/
├── frontend/ # 前端项目
│ ├── src/
│ │ ├── views/ # 页面视图
│ │ ├── components/ # 组件
│ │ ├── stores/ # 状态管理
│ │ ├── api/ # API接口
│ │ └── utils/ # 工具函数
│ └── package.json

├── backend/ # 后端项目
│ ├── app/
│ │ ├── api/v1/ # API路由
│ │ ├── services/ # 业务逻辑
│ │ ├── models/ # 数据模型
│ │ ├── tasks/ # Celery任务
│ │ └── websocket/ # WebSocket
│ └── requirements.txt

├── docker-compose.yml # Docker编排
├── nginx.conf # Nginx配置
└── README.md

架构设计原则

在设计这个系统时,我遵循了以下原则:

1. 分层清晰

  • 每层只关注自己的职责

  • 层与层之间通过接口通信

  • 便于独立开发和测试

2. 松耦合

  • 前后端分离,独立部署

  • 服务之间通过消息队列解耦

  • 数据源可替换(Tushare/AKShare)

3. 可扩展

  • 新增功能只需添加新模块

  • 支持水平扩展(多实例部署)

  • 预留了AI分析等扩展接口

4. 高可用

  • Redis缓存降低数据库压力

  • Celery异步处理耗时任务

  • 完善的错误处理和日志

总结

本文介绍了A股分析系统的整体架构设计:

层级

技术选型

核心职责

用户层

Vue 3 + AntD

界面展示、用户交互

接入层

前后端分离怎么部署(系统架构设计:如何支撑5000+股票的实时分析)

Nginx

反向代理、负载均衡

应用层

FastAPI

API服务、WebSocket

业务层

Python Services

核心业务逻辑

数据层

PostgreSQL + Redis

数据存储、缓存

任务层

Celery

异步任务、定时调度

下期预告: 《10分钟用Docker启动整个系统》

我会手把手教你:

  • Docker环境准备

  • 一键启动所有服务

  • Tushare Token配置

  • 常见问题解决

有问题欢迎留言讨论

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有