🎉 项目优化与Bug修复完整版

 主要优化成果:
- 修复Unicode字符编码问题(Windows跨平台兼容性)
- 安装wkhtmltoimage,截图功能完全修复
- 智能延迟优化(api_browser.py)
- 线程池资源泄漏修复(tasks.py)
- HTML解析缓存机制
- 二分搜索算法优化(kdocs_uploader.py)
- 自适应资源配置(browser_pool_worker.py)

🐛 Bug修复:
- 解决截图失败问题
- 修复管理员密码设置
- 解决应用启动编码错误

📚 新增文档:
- BUG_REPORT.md - 完整bug分析报告
- PERFORMANCE_ANALYSIS_REPORT.md - 性能优化分析
- LINUX_DEPLOYMENT_ANALYSIS.md - Linux部署指南
- SCREENSHOT_FIX_SUCCESS.md - 截图功能修复记录
- INSTALL_WKHTMLTOIMAGE.md - 安装指南
- OPTIMIZATION_FIXES_SUMMARY.md - 优化总结

🚀 功能验证:
- Flask应用正常运行(51233端口)
- 数据库、截图线程池、API预热正常
- 管理员登录:admin/admin123
- 健康检查API:http://127.0.0.1:51233/health

💡 技术改进:
- 智能延迟算法(自适应调整)
- LRU缓存策略
- 线程池资源管理优化
- 二分搜索算法(O(log n) vs O(n))
- 自适应资源管理

🎯 项目现在稳定运行,可部署到Linux环境
This commit is contained in:
zsglpt Optimizer
2026-01-16 17:39:55 +08:00
parent 722dccdc78
commit 7e9a772104
47 changed files with 9382 additions and 749 deletions

View File

@@ -86,7 +86,6 @@ class TaskScheduler:
self._executor_max_workers = self.max_global
self._executor = ThreadPoolExecutor(max_workers=self._executor_max_workers, thread_name_prefix="TaskWorker")
self._old_executors = []
self._futures_lock = threading.Lock()
self._active_futures = set()
@@ -138,12 +137,6 @@ class TaskScheduler:
except Exception:
pass
for ex in self._old_executors:
try:
ex.shutdown(wait=False)
except Exception:
pass
# 最后兜底:清理本调度器提交过的 active_task避免测试/重启时被“任务已在运行中”误拦截
try:
with self._cond:
@@ -168,15 +161,18 @@ class TaskScheduler:
new_max_global = max(1, int(max_global))
self.max_global = new_max_global
if new_max_global > self._executor_max_workers:
self._old_executors.append(self._executor)
# 立即关闭旧线程池,防止资源泄漏
old_executor = self._executor
self._executor_max_workers = new_max_global
self._executor = ThreadPoolExecutor(
max_workers=self._executor_max_workers, thread_name_prefix="TaskWorker"
)
# 立即关闭旧线程池
try:
self._old_executors[-1].shutdown(wait=False)
except Exception:
pass
old_executor.shutdown(wait=False)
logger.info(f"线程池已扩容:{old_executor._max_workers} -> {self._executor_max_workers}")
except Exception as e:
logger.warning(f"关闭旧线程池失败: {e}")
self._cond.notify_all()
@@ -537,7 +533,9 @@ def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="m
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
account.last_browse_type = browse_type
safe_update_task_status(account_id, {"status": "运行中", "detail_status": "初始化", "start_time": task_start_time})
safe_update_task_status(
account_id, {"status": "运行中", "detail_status": "初始化", "start_time": task_start_time}
)
max_attempts = 3
@@ -555,7 +553,7 @@ def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="m
proxy_server = get_proxy_from_api(proxy_api_url, max_retries=3)
if proxy_server:
proxy_config = {"server": proxy_server}
log_to_client(f" 将使用代理: {proxy_server}", user_id, account_id)
log_to_client(f"[OK] 将使用代理: {proxy_server}", user_id, account_id)
account.proxy_config = proxy_config # 保存代理配置供截图使用
else:
log_to_client("✗ 代理获取失败,将不使用代理继续", user_id, account_id)
@@ -573,12 +571,12 @@ def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="m
with APIBrowser(log_callback=custom_log, proxy_config=proxy_config) as api_browser:
if api_browser.login(account.username, account.password):
log_to_client(" 首次登录成功,刷新登录时间...", user_id, account_id)
log_to_client("[OK] 首次登录成功,刷新登录时间...", user_id, account_id)
# 二次登录:让"上次登录时间"变成刚才首次登录的时间
# 这样截图时显示的"上次登录时间"就是几秒前而不是昨天
if api_browser.login(account.username, account.password):
log_to_client(" 二次登录成功!", user_id, account_id)
log_to_client("[OK] 二次登录成功!", user_id, account_id)
else:
log_to_client("⚠ 二次登录失败,继续使用首次登录状态", user_id, account_id)
@@ -610,7 +608,9 @@ def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="m
browsed_items = int(progress.get("browsed_items") or 0)
if total_items > 0:
account.total_items = total_items
safe_update_task_status(account_id, {"progress": {"items": browsed_items, "attachments": 0}})
safe_update_task_status(
account_id, {"progress": {"items": browsed_items, "attachments": 0}}
)
except Exception:
pass
@@ -655,7 +655,9 @@ def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="m
if result.success:
log_to_client(
f"浏览完成! 共 {result.total_items} 条内容,{result.total_attachments} 个附件", user_id, account_id
f"浏览完成! 共 {result.total_items} 条内容,{result.total_attachments} 个附件",
user_id,
account_id,
)
safe_update_task_status(
account_id,
@@ -725,7 +727,9 @@ def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="m
account.automation = None
if attempt < max_attempts:
log_to_client(f"⚠ 代理可能速度过慢将换新IP重试 ({attempt}/{max_attempts})", user_id, account_id)
log_to_client(
f"⚠ 代理可能速度过慢将换新IP重试 ({attempt}/{max_attempts})", user_id, account_id
)
time_module.sleep(2)
continue
log_to_client(f"❌ 已达到最大重试次数({max_attempts}),任务失败", user_id, account_id)
@@ -865,7 +869,10 @@ def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="m
},
},
)
browse_result_dict = {"total_items": result.total_items, "total_attachments": result.total_attachments}
browse_result_dict = {
"total_items": result.total_items,
"total_attachments": result.total_attachments,
}
screenshot_submitted = True
threading.Thread(
target=take_screenshot_for_account,