✨ 优化浏览器池和并发配置
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:
@@ -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:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user