优化浏览器池和并发配置

1. 浏览器池改为按需启动模式
   - 启动时不创建浏览器,有截图任务时才启动
   - 空闲5分钟后自动关闭浏览器释放资源

2. 修复截图并发数保存问题
   - 修复database.py中缺少保存max_screenshot_concurrent的代码

3. 去掉并发数上限限制
   - 管理员可自由设置并发数,不再限制1-20/1-5

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-10 20:31:49 +08:00
parent f46c662fe5
commit a8e8bbe8a2
4 changed files with 43 additions and 36 deletions

View File

@@ -98,26 +98,33 @@ class BrowserWorker(threading.Thread):
return self._create_browser()
def run(self):
"""工作线程主循环"""
self.log("Worker启动")
# 初始创建浏览器
if not self._create_browser():
self.log("初始浏览器创建失败Worker退出")
return
"""工作线程主循环 - 按需启动浏览器模式"""
self.log("Worker启动(按需模式,等待任务时不占用浏览器资源)")
last_task_time = 0
IDLE_TIMEOUT = 300 # 空闲5分钟后关闭浏览器
while self.running:
try:
# 从队列获取任务(带超时,以便能响应停止信号)
# 从队列获取任务(带超时,以便能响应停止信号和空闲检查
self.idle = True
task = self.task_queue.get(timeout=1)
try:
task = self.task_queue.get(timeout=10)
except queue.Empty:
# 检查是否需要关闭空闲的浏览器
if self.browser_instance and last_task_time > 0:
idle_time = time.time() - last_task_time
if idle_time > IDLE_TIMEOUT:
self.log(f"空闲{int(idle_time)}秒,关闭浏览器释放资源")
self._close_browser()
continue
self.idle = False
if task is None: # None作为停止信号
self.log("收到停止信号")
break
# 确保浏览器可用
# 按需创建或确保浏览器可用
if not self._ensure_browser():
self.log("浏览器不可用,任务失败")
task['callback'](None, "浏览器不可用")
@@ -140,20 +147,19 @@ class BrowserWorker(threading.Thread):
result = task_func(self.browser_instance, *task_args, **task_kwargs)
callback(result, None)
self.log(f"任务执行成功")
last_task_time = time.time()
except Exception as e:
self.log(f"任务执行失败: {e}")
callback(None, str(e))
self.failed_tasks += 1
last_task_time = time.time()
# 任务失败后,检查浏览器健康
if not self._check_browser_health():
self.log("任务失败导致浏览器异常,将在下次任务前重建")
self._close_browser()
except queue.Empty:
# 队列为空,继续等待
continue
except Exception as e:
self.log(f"Worker出错: {e}")
time.sleep(1)
@@ -186,12 +192,12 @@ class BrowserWorkerPool:
print(f"[浏览器池] {message}")
def initialize(self):
"""初始化工作线程池"""
"""初始化工作线程池(按需模式,启动时不创建浏览器)"""
with self.lock:
if self.initialized:
return
self.log(f"正在初始化工作线程池({self.pool_size}个worker...")
self.log(f"正在初始化工作线程池({self.pool_size}个worker,按需启动浏览器...")
for i in range(self.pool_size):
worker = BrowserWorker(
@@ -202,11 +208,8 @@ class BrowserWorkerPool:
worker.start()
self.workers.append(worker)
# 等待所有worker准备就绪
time.sleep(2)
self.initialized = True
self.log(f"✓ 工作线程池初始化完成({self.pool_size}个worker就绪)")
self.log(f"✓ 工作线程池初始化完成({self.pool_size}个worker就绪,浏览器将在有任务时按需启动")
def submit_task(self, task_func: Callable, callback: Callable, *args, **kwargs) -> bool:
"""