性能优化: 任务列表瘦身+详情分页+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:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user