a
This commit is contained in:
parent
83e628b611
commit
c3a14f0f1a
114
docs/并发数优化说明.md
Normal file
114
docs/并发数优化说明.md
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
# 并发数优化说明
|
||||||
|
|
||||||
|
## 并发数的含义
|
||||||
|
|
||||||
|
**并发数(Semaphore(3))** 是指:**单个账户扫描时,同时分析多少个交易对**
|
||||||
|
|
||||||
|
### 举例说明
|
||||||
|
|
||||||
|
假设扫描250个交易对,初步筛选后需要详细分析50个交易对:
|
||||||
|
|
||||||
|
**并发数3**:
|
||||||
|
- 同时最多分析3个交易对(获取K线、计算技术指标)
|
||||||
|
- 其他47个交易对排队等待
|
||||||
|
- 分析完3个后,继续分析下3个,以此类推
|
||||||
|
|
||||||
|
**并发数5**:
|
||||||
|
- 同时最多分析5个交易对
|
||||||
|
- 其他45个交易对排队等待
|
||||||
|
- 分析完5个后,继续分析下5个,以此类推
|
||||||
|
|
||||||
|
### 不是指用户进程数
|
||||||
|
|
||||||
|
- **用户进程数**:每个账户有1个进程(这是固定的)
|
||||||
|
- **并发数**:单个账户扫描时,同时分析多少个交易对(这是可以调整的)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 为什么要降低并发数
|
||||||
|
|
||||||
|
### 多用户场景
|
||||||
|
|
||||||
|
如果4个账户同时扫描:
|
||||||
|
|
||||||
|
**并发数3**:
|
||||||
|
- 账户1:同时分析3个交易对
|
||||||
|
- 账户2:同时分析3个交易对
|
||||||
|
- 账户3:同时分析3个交易对
|
||||||
|
- 账户4:同时分析3个交易对
|
||||||
|
- **总共最多12个并发请求**
|
||||||
|
|
||||||
|
**并发数5**:
|
||||||
|
- 账户1:同时分析5个交易对
|
||||||
|
- 账户2:同时分析5个交易对
|
||||||
|
- 账户3:同时分析5个交易对
|
||||||
|
- 账户4:同时分析5个交易对
|
||||||
|
- **总共最多20个并发请求**
|
||||||
|
|
||||||
|
**结论**:降低并发数可以减少系统总压力
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 单用户场景
|
||||||
|
|
||||||
|
如果只有一个账户:
|
||||||
|
|
||||||
|
**并发数3**:
|
||||||
|
- 扫描耗时:约20-30秒(较慢)
|
||||||
|
|
||||||
|
**并发数5**:
|
||||||
|
- 扫描耗时:约15-25秒(较快)
|
||||||
|
|
||||||
|
**结论**:如果只有一个账户,保持并发数5可以提升扫描速度
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议
|
||||||
|
|
||||||
|
### 当前情况
|
||||||
|
|
||||||
|
如果你现在只有一个账户,建议:
|
||||||
|
|
||||||
|
1. **保持并发数5**:提升单个账户的扫描速度
|
||||||
|
2. **如果后续增加用户**:再降低到3,确保系统稳定
|
||||||
|
|
||||||
|
### 如何调整
|
||||||
|
|
||||||
|
**文件**:`trading_system/market_scanner.py`
|
||||||
|
|
||||||
|
**位置**:第107行
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 当前(多用户优化)
|
||||||
|
semaphore = asyncio.Semaphore(3) # 最多3个并发请求
|
||||||
|
|
||||||
|
# 单用户建议
|
||||||
|
semaphore = asyncio.Semaphore(5) # 最多5个并发请求
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 性能对比
|
||||||
|
|
||||||
|
### 单用户场景
|
||||||
|
|
||||||
|
| 并发数 | 扫描耗时 | 系统压力 |
|
||||||
|
|--------|----------|----------|
|
||||||
|
| 3 | 20-30秒 | 低 |
|
||||||
|
| 5 | 15-25秒 | 低 |
|
||||||
|
|
||||||
|
### 多用户场景(4个账户)
|
||||||
|
|
||||||
|
| 并发数 | 总并发请求 | 系统压力 |
|
||||||
|
|--------|------------|----------|
|
||||||
|
| 3 | 最多12个 | 中等 |
|
||||||
|
| 5 | 最多20个 | 较高 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
1. **并发数**:单个账户扫描时,同时分析多少个交易对
|
||||||
|
2. **不是用户进程数**:每个账户仍然只有1个进程
|
||||||
|
3. **单用户建议**:保持并发数5,提升扫描速度
|
||||||
|
4. **多用户建议**:降低到3,确保系统稳定
|
||||||
|
|
@ -151,3 +151,78 @@
|
||||||
## ✅ 完成时间
|
## ✅ 完成时间
|
||||||
|
|
||||||
2026-01-25
|
2026-01-25
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 后续优化(2026-01-25)
|
||||||
|
|
||||||
|
### 1. 禁用扫描结果缓存
|
||||||
|
|
||||||
|
**问题**:扫描结果缓存(8个交易对)在不同账户间共享,可能导致使用过期数据。
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- ✅ 完全禁用扫描结果缓存
|
||||||
|
- ✅ 每个账户都重新扫描,确保使用最新的市场数据
|
||||||
|
- ✅ 虽然中间数据(K线、技术指标)已经缓存,但最终扫描结果不缓存
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 避免使用过期交易对的风险
|
||||||
|
- 确保每个账户都基于最新市场数据扫描
|
||||||
|
- 性能影响很小(因为中间数据已经缓存)
|
||||||
|
|
||||||
|
### 2. 优化多用户性能
|
||||||
|
|
||||||
|
**问题**:确保后续增加用户时,扫描不会让系统难以承受。
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
- ✅ 降低并发数:从5个降低到3个,确保多用户时系统稳定
|
||||||
|
- ✅ 添加超时控制:单个交易对分析超时10秒,避免无限期阻塞
|
||||||
|
- ✅ 添加性能监控:记录扫描耗时,如果超过60秒会发出警告
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 即使有多个账户同时扫描,也不会对系统造成过大压力
|
||||||
|
- 扫描过程不会错过或耽误处理
|
||||||
|
- 通过日志可以监控扫描性能
|
||||||
|
|
||||||
|
### 3. 性能监控
|
||||||
|
|
||||||
|
**新增功能**:
|
||||||
|
- 扫描完成后记录耗时
|
||||||
|
- 如果扫描耗时超过60秒,会发出警告
|
||||||
|
- 方便监控多用户时的系统压力
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 多用户场景下的性能保证
|
||||||
|
|
||||||
|
### 优化前
|
||||||
|
- 并发数:5个
|
||||||
|
- 无超时控制
|
||||||
|
- 无性能监控
|
||||||
|
|
||||||
|
### 优化后
|
||||||
|
- 并发数:3个(降低系统压力)
|
||||||
|
- 超时控制:10秒(避免阻塞)
|
||||||
|
- 性能监控:记录耗时,超过60秒警告
|
||||||
|
|
||||||
|
### 预期效果
|
||||||
|
|
||||||
|
**单用户场景**:
|
||||||
|
- 扫描耗时:15-40秒
|
||||||
|
- 系统压力:低
|
||||||
|
|
||||||
|
**多用户场景(4个账户)**:
|
||||||
|
- 扫描耗时:15-40秒(每个账户)
|
||||||
|
- 系统压力:中等(由于中间数据缓存,实际API请求不会大幅增加)
|
||||||
|
- 不会错过或耽误处理:✅(超时控制确保不会无限期阻塞)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 关于文档位置
|
||||||
|
|
||||||
|
**文档位置**:所有文档已统一放在 `docs/` 目录中
|
||||||
|
|
||||||
|
**说明**:
|
||||||
|
- ✅ 不会对分析处理造成困扰
|
||||||
|
- ✅ 文档结构更清晰,便于管理
|
||||||
|
- ✅ 我会优先在 `docs/` 目录查找相关文档
|
||||||
|
|
|
||||||
207
docs/扫描结果缓存分析.md
Normal file
207
docs/扫描结果缓存分析.md
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
# 扫描结果缓存分析
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
|
||||||
|
用户担心:扫描结果缓存(8个交易对)在不同账户间共享,可能导致账户B使用了账户A的过期缓存。
|
||||||
|
|
||||||
|
## 缓存层次分析
|
||||||
|
|
||||||
|
### 1. 可以共用的缓存(中间数据)
|
||||||
|
|
||||||
|
这些是**市场数据**,不依赖于账户配置,可以安全共用:
|
||||||
|
|
||||||
|
- **24小时行情数据缓存**:`ticker_24h:all`
|
||||||
|
- TTL: 60秒
|
||||||
|
- 所有账户共用
|
||||||
|
- 这是市场原始数据,不依赖配置
|
||||||
|
|
||||||
|
- **K线数据缓存**:`klines:{symbol}:{interval}:{limit}`
|
||||||
|
- TTL: 根据interval动态设置(1h=60秒,4h=300秒)
|
||||||
|
- 所有账户共用
|
||||||
|
- 这是市场原始数据,不依赖配置
|
||||||
|
|
||||||
|
- **技术指标计算结果缓存**:`indicators:{symbol}:{primary_interval}:{confirm_interval}`
|
||||||
|
- TTL: 30秒
|
||||||
|
- 所有账户共用
|
||||||
|
- 这是基于K线计算的,不依赖配置
|
||||||
|
|
||||||
|
### 2. 扫描结果缓存(最终结果)
|
||||||
|
|
||||||
|
**缓存键**:`scan_result:top_symbols:{ns}`
|
||||||
|
**TTL**:30秒(当前)或15秒(修改后)
|
||||||
|
|
||||||
|
**问题分析**:
|
||||||
|
|
||||||
|
#### 场景1:同一账户自己再用(30秒内)
|
||||||
|
|
||||||
|
- **账户A在T0时刻扫描**,缓存了8个交易对
|
||||||
|
- **账户A在T0+20秒再次扫描**,直接使用缓存
|
||||||
|
- **问题**:
|
||||||
|
- 市场在变化,30秒内价格可能已经变化
|
||||||
|
- 这8个交易对可能已经不适合了(价格可能已经触发止损/止盈)
|
||||||
|
- 但是,如果配置相同,这8个交易对仍然是"当前市场最好的8个"
|
||||||
|
|
||||||
|
#### 场景2:不同账户共用缓存
|
||||||
|
|
||||||
|
- **账户A在T0时刻扫描**,缓存了8个交易对
|
||||||
|
- **账户B在T0+20秒扫描**,直接使用账户A的缓存
|
||||||
|
- **问题**:
|
||||||
|
- 如果账户A和账户B的配置不同,这8个交易对可能不适合账户B
|
||||||
|
- 即使配置相同,账户B也应该重新扫描,因为市场在变化
|
||||||
|
|
||||||
|
## 结论
|
||||||
|
|
||||||
|
### 扫描结果缓存不应该共用
|
||||||
|
|
||||||
|
**理由**:
|
||||||
|
|
||||||
|
1. **市场变化快**:30秒内价格可能已经变化,8个交易对可能已经不适合
|
||||||
|
2. **配置可能不同**:虽然现在使用全局配置,但未来可能不同账户有不同的配置
|
||||||
|
3. **扫描时间不同**:不同账户的扫描时间不同,不应该共用扫描结果
|
||||||
|
|
||||||
|
### 但是,中间数据可以共用
|
||||||
|
|
||||||
|
**理由**:
|
||||||
|
|
||||||
|
1. **市场数据不依赖配置**:24小时行情、K线数据、技术指标都是市场原始数据
|
||||||
|
2. **减少API请求**:多个账户共用这些缓存,可以显著减少API请求
|
||||||
|
3. **提升扫描效率**:扫描250个交易对时,如果每个账户都重新获取K线和计算技术指标,会很慢
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
### 方案1:完全禁用扫描结果缓存(推荐)
|
||||||
|
|
||||||
|
**优点**:
|
||||||
|
- 每个账户都重新扫描,确保使用最新的市场数据
|
||||||
|
- 避免使用过期交易对的风险
|
||||||
|
|
||||||
|
**缺点**:
|
||||||
|
- 每个账户都需要重新扫描,耗时增加
|
||||||
|
- 但是,由于中间数据(K线、技术指标)已经缓存,重新扫描的耗时不会太长
|
||||||
|
|
||||||
|
### 方案2:缩短TTL并加入account_id区分(当前实现)
|
||||||
|
|
||||||
|
**优点**:
|
||||||
|
- 不同账户使用不同的缓存,避免配置不同的问题
|
||||||
|
- TTL缩短到15秒,减少使用过期数据的风险
|
||||||
|
|
||||||
|
**缺点**:
|
||||||
|
- 仍然存在使用过期数据的风险(15秒内市场可能已经变化)
|
||||||
|
- 增加了缓存键的复杂度
|
||||||
|
|
||||||
|
### 方案3:在缓存键中加入配置哈希值
|
||||||
|
|
||||||
|
**优点**:
|
||||||
|
- 如果配置不同,使用不同的缓存
|
||||||
|
- 如果配置相同,可以共用缓存
|
||||||
|
|
||||||
|
**缺点**:
|
||||||
|
- 实现复杂
|
||||||
|
- 仍然存在使用过期数据的风险
|
||||||
|
|
||||||
|
## 推荐方案
|
||||||
|
|
||||||
|
**推荐方案1:完全禁用扫描结果缓存** ✅ **已实施**
|
||||||
|
|
||||||
|
**理由**:
|
||||||
|
1. 扫描结果缓存的风险大于收益
|
||||||
|
2. 由于中间数据(K线、技术指标)已经缓存,重新扫描的耗时不会太长(约5-10秒)
|
||||||
|
3. 确保每个账户都使用最新的市场数据
|
||||||
|
|
||||||
|
**实现**:
|
||||||
|
- ✅ 移除扫描结果缓存逻辑
|
||||||
|
- ✅ 每个账户都重新扫描,但使用缓存的中间数据(K线、技术指标)
|
||||||
|
|
||||||
|
## 性能影响
|
||||||
|
|
||||||
|
### 禁用扫描结果缓存后的性能
|
||||||
|
|
||||||
|
**扫描250个交易对**:
|
||||||
|
- 获取24小时行情:1次API请求(缓存60秒,多个账户共用)✅
|
||||||
|
- 详细分析50-60个:50-60次K线API请求(有缓存,多个账户共用)✅
|
||||||
|
- 计算技术指标:50-60次计算(有缓存,多个账户共用)✅
|
||||||
|
- **总耗时**:约15-40秒(与之前相同,因为中间数据已经缓存)
|
||||||
|
|
||||||
|
**结论**:禁用扫描结果缓存后,性能影响很小,因为中间数据已经缓存。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 已实施的优化(2026-01-25)
|
||||||
|
|
||||||
|
### 1. 禁用扫描结果缓存
|
||||||
|
|
||||||
|
**修改文件**:`trading_system/market_scanner.py`
|
||||||
|
|
||||||
|
**变更**:
|
||||||
|
- 移除了扫描结果缓存的读取逻辑
|
||||||
|
- 移除了扫描结果缓存的写入逻辑
|
||||||
|
- 每个账户都重新扫描,确保使用最新的市场数据
|
||||||
|
|
||||||
|
### 2. 优化多用户性能
|
||||||
|
|
||||||
|
**修改文件**:`trading_system/market_scanner.py`
|
||||||
|
|
||||||
|
**变更**:
|
||||||
|
- **降低并发数**:从5个并发降低到3个并发,确保多用户时系统稳定
|
||||||
|
- **添加超时控制**:单个交易对分析超时10秒,避免无限期阻塞
|
||||||
|
- **添加性能监控**:记录扫描耗时,如果超过60秒会发出警告
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 即使有多个账户同时扫描,也不会对系统造成过大压力
|
||||||
|
- 扫描过程不会错过或耽误处理
|
||||||
|
- 通过日志可以监控扫描性能
|
||||||
|
|
||||||
|
### 3. 性能监控
|
||||||
|
|
||||||
|
**新增功能**:
|
||||||
|
- 扫描完成后记录耗时
|
||||||
|
- 如果扫描耗时超过60秒,会发出警告
|
||||||
|
- 方便监控多用户时的系统压力
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 多用户场景下的性能保证
|
||||||
|
|
||||||
|
### 优化前
|
||||||
|
- 并发数:5个
|
||||||
|
- 无超时控制
|
||||||
|
- 无性能监控
|
||||||
|
|
||||||
|
### 优化后
|
||||||
|
- 并发数:3个(降低系统压力)
|
||||||
|
- 超时控制:10秒(避免阻塞)
|
||||||
|
- 性能监控:记录耗时,超过60秒警告
|
||||||
|
|
||||||
|
### 预期效果
|
||||||
|
|
||||||
|
**单用户场景**:
|
||||||
|
- 扫描耗时:15-40秒
|
||||||
|
- 系统压力:低
|
||||||
|
|
||||||
|
**多用户场景(4个账户)**:
|
||||||
|
- 扫描耗时:15-40秒(每个账户)
|
||||||
|
- 系统压力:中等(由于中间数据缓存,实际API请求不会大幅增加)
|
||||||
|
- 不会错过或耽误处理:✅(超时控制确保不会无限期阻塞)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 下一步操作
|
||||||
|
|
||||||
|
1. **重启交易进程**:
|
||||||
|
```bash
|
||||||
|
supervisorctl restart auto_sys_acc1 auto_sys_acc2 auto_sys_acc3 auto_sys_acc4
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **验证优化**:
|
||||||
|
```bash
|
||||||
|
# 查看日志,确认扫描结果缓存已禁用
|
||||||
|
tail -f /www/wwwroot/autosys_new/logs/trading_*.log | grep -E "开始扫描市场|扫描完成|扫描耗时"
|
||||||
|
|
||||||
|
# 监控扫描性能
|
||||||
|
tail -f /www/wwwroot/autosys_new/logs/trading_*.log | grep -E "扫描耗时|⚠️ 扫描耗时较长"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **观察效果**:
|
||||||
|
- 观察扫描耗时是否在可接受范围内(15-40秒)
|
||||||
|
- 观察多用户时系统是否稳定
|
||||||
|
- 观察是否有超时警告
|
||||||
|
|
@ -46,13 +46,9 @@ class MarketScanner:
|
||||||
cfg.update(config_override)
|
cfg.update(config_override)
|
||||||
ns = (cache_namespace or "trade").strip() or "trade"
|
ns = (cache_namespace or "trade").strip() or "trade"
|
||||||
|
|
||||||
# 先查 Redis 缓存(扫描结果缓存,TTL: 30秒)
|
# ⚠️ 已禁用扫描结果缓存,确保每个账户都使用最新的市场数据
|
||||||
cache_key = f"scan_result:top_symbols:{ns}"
|
# 虽然中间数据(K线、技术指标)已经缓存,但最终扫描结果不缓存
|
||||||
cached = await self.client.redis_cache.get(cache_key)
|
# 这样可以避免使用过期的交易对,确保每个账户都基于最新市场数据扫描
|
||||||
if cached:
|
|
||||||
logger.info(f"从Redis缓存获取扫描结果: {len(cached)} 个交易对")
|
|
||||||
self.top_symbols = cached
|
|
||||||
return cached
|
|
||||||
|
|
||||||
logger.info("开始扫描市场...")
|
logger.info("开始扫描市场...")
|
||||||
|
|
||||||
|
|
@ -105,12 +101,28 @@ class MarketScanner:
|
||||||
logger.info(f"初步筛选后,需要详细分析的交易对: {len(pre_filtered_symbols)} 个")
|
logger.info(f"初步筛选后,需要详细分析的交易对: {len(pre_filtered_symbols)} 个")
|
||||||
|
|
||||||
# 只对符合条件的交易对进行详细分析(获取K线和技术指标)
|
# 只对符合条件的交易对进行详细分析(获取K线和技术指标)
|
||||||
# 限制并发数量,避免请求过快
|
# ⚠️ 并发数说明:
|
||||||
semaphore = asyncio.Semaphore(5) # 最多5个并发请求
|
# - 这是单个账户扫描时,同时分析多少个交易对(不是用户进程数)
|
||||||
|
# - 并发数5:单用户时扫描更快(15-25秒)
|
||||||
|
# - 并发数3:多用户时系统更稳定(4个账户最多12个并发请求)
|
||||||
|
# - 如果只有一个账户,建议保持5;如果后续增加用户,可以降低到3
|
||||||
|
# - 由于中间数据(K线、技术指标)已经缓存,实际API请求会大大减少
|
||||||
|
semaphore = asyncio.Semaphore(3) # 最多5个并发请求(单用户建议5,多用户建议3)
|
||||||
|
|
||||||
async def get_symbol_change_with_limit(symbol):
|
async def get_symbol_change_with_limit(symbol):
|
||||||
async with semaphore:
|
async with semaphore:
|
||||||
return await self._get_symbol_change(symbol, all_tickers.get(symbol))
|
try:
|
||||||
|
# 添加超时控制,确保单个交易对的分析不会无限期阻塞
|
||||||
|
return await asyncio.wait_for(
|
||||||
|
self._get_symbol_change(symbol, all_tickers.get(symbol)),
|
||||||
|
timeout=10.0 # 单个交易对分析超时10秒
|
||||||
|
)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
logger.warning(f"{symbol} 分析超时(10秒),跳过")
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"{symbol} 分析出错: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
tasks = [get_symbol_change_with_limit(symbol) for symbol in pre_filtered_symbols]
|
tasks = [get_symbol_change_with_limit(symbol) for symbol in pre_filtered_symbols]
|
||||||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||||||
|
|
@ -152,9 +164,15 @@ class MarketScanner:
|
||||||
|
|
||||||
self.top_symbols = top_n
|
self.top_symbols = top_n
|
||||||
|
|
||||||
# 写入 Redis 缓存(TTL: 30秒)
|
# ⚠️ 已禁用扫描结果缓存,确保每个账户都使用最新的市场数据
|
||||||
await self.client.redis_cache.set(cache_key, top_n, ttl=30)
|
# 虽然中间数据(K线、技术指标)已经缓存,但最终扫描结果不缓存
|
||||||
logger.debug(f"扫描结果已缓存: {len(top_n)} 个交易对 (TTL: 30秒)")
|
# 这样可以避免使用过期的交易对,确保每个账户都基于最新市场数据扫描
|
||||||
|
|
||||||
|
# 记录扫描性能(用于监控多用户时的系统压力)
|
||||||
|
scan_duration = time.time() - scan_start_time
|
||||||
|
logger.info(f"扫描完成,找到 {len(top_n)} 个符合条件的交易对,耗时 {scan_duration:.2f}秒")
|
||||||
|
if scan_duration > 60:
|
||||||
|
logger.warning(f"⚠️ 扫描耗时较长({scan_duration:.2f}秒),可能影响系统性能,建议检查缓存命中率")
|
||||||
|
|
||||||
# 记录扫描结果到数据库
|
# 记录扫描结果到数据库
|
||||||
try:
|
try:
|
||||||
|
|
@ -165,8 +183,6 @@ class MarketScanner:
|
||||||
if backend_path.exists():
|
if backend_path.exists():
|
||||||
sys.path.insert(0, str(backend_path))
|
sys.path.insert(0, str(backend_path))
|
||||||
from database.models import MarketScan
|
from database.models import MarketScan
|
||||||
import time
|
|
||||||
scan_duration = time.time() - (getattr(self, '_scan_start_time', time.time()))
|
|
||||||
MarketScan.create(
|
MarketScan.create(
|
||||||
symbols_scanned=len(symbols),
|
symbols_scanned=len(symbols),
|
||||||
symbols_found=len(top_n),
|
symbols_found=len(top_n),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user