性能优化: 任务列表瘦身+详情分页+auto状态独立存储+磁盘统计缓存+db异步同步; 统计数值未读取时显示-

- /api/tasks 响应 1.57MB -> 12KB (latest_run 只带摘要, 一次读 runs.json)
- /api/stats 磁盘占用加 30s 缓存, 去除重复全量读
- 详情接口分页返回 results (默认100条/页), 前端表格分页+页码跳转
- auto 任务 pending/visited 队列迁移到 data/auto_state/ 独立文件 (tasks.json 1.6MB -> 14KB)
- MySQL 同步改后台线程异步执行 (db.sync_run_async/upsert_task_async), 不再阻塞爬虫和 API
- 启动时自动迁移存量 auto 状态
- 统计/回收站/运行中数值在未读到真实数据前显示 '-'
This commit is contained in:
2026-08-12 09:28:16 +08:00
parent 66ba1a7cfc
commit 796e667533
8 changed files with 47204 additions and 79 deletions
+35
View File
@@ -5,9 +5,11 @@ MySQL 记录层: 任务 / 运行 / 爬取结果 写入数据库
- 爬取成功/失败均有 status 标记 (OK / FAIL), 运行记录有 run 状态标记
- 所有操作容错: 数据库不可用时不影响爬取主流程 (仅打印日志)
"""
import copy
import json
import os
import time
from concurrent.futures import ThreadPoolExecutor
import pymysql
@@ -101,6 +103,39 @@ def _safe(fn, *args, **kwargs):
print(f"[db] 操作失败: {e}", flush=True)
# ---------------- 异步同步 (避免远程 MySQL 阻塞爬虫/API 主流程) ----------------
_db_executor = ThreadPoolExecutor(max_workers=2, thread_name_prefix="db-sync")
def upsert_task_async(task):
"""异步写入/更新任务 (不阻塞调用方)"""
try:
snap = copy.deepcopy(task)
_db_executor.submit(upsert_task, snap)
except Exception as e:
print(f"[db] 异步任务同步失败: {e}", flush=True)
def sync_run_async(run):
"""异步同步运行记录+爬取结果; 完成后把 _db_count 回写到主线程 run 对象"""
try:
snap = copy.deepcopy(run)
def _work():
upsert_run(snap)
results = snap.get("results", [])
synced = snap.get("_db_count", 0)
if len(results) > synced:
insert_results(snap, results[synced:])
snap["_db_count"] = len(results)
run["_db_count"] = snap["_db_count"]
_db_executor.submit(_work)
except Exception as e:
print(f"[db] 异步运行同步失败: {e}", flush=True)
def init_db():
"""建库建表 (幂等)"""
try: