支持服务启动后自动预热转图浏览器

变更项:1) markdown_to_image 新增预热方法 warmup_md2img_browser/warmup_md2img_browser_sync,用于提前拉起常驻浏览器。2) main.py 启动流程新增后台预热线程,服务启动后自动执行转图浏览器预热。3) 预热失败仅记录日志不阻塞主服务,运行期仍可按需自动重建浏览器。4) 补充中文注释说明预热目的与降级策略。
This commit is contained in:
liuwei
2026-04-17 09:28:36 +08:00
parent f90c0720b3
commit 6af91756d3
2 changed files with 41 additions and 0 deletions

15
main.py
View File

@@ -5,6 +5,7 @@ import threading
from admin.GlancesMonitor import GlancesMonitor
from utils.decorator.async_job import async_job
from utils.markdown_to_image import warmup_md2img_browser_sync
from configuration import Config
from robot import Robot
@@ -106,6 +107,20 @@ def main():
except Exception as e:
robot.LOG.error(f"GlancesMonitor服务器启动失败: {e}")
# 启动后异步预热 Markdown 转图浏览器,降低首个转图任务冷启动失败概率。
try:
def _warmup_md2img():
ok = warmup_md2img_browser_sync(timeout_seconds=60)
if ok:
robot.LOG.info("Markdown 转图浏览器预热成功")
else:
robot.LOG.warning("Markdown 转图浏览器预热失败,运行期将按需重试")
warmup_thread = threading.Thread(target=_warmup_md2img, daemon=True)
warmup_thread.start()
except Exception as e:
robot.LOG.error(f"启动 Markdown 转图预热线程失败: {e}")
robot.LOG.info(f"=" * 50)
asyncio.run(async_job.run_all())
# 让机器人一直跑

View File

@@ -610,6 +610,32 @@ def _get_browser_manager() -> _PersistentBrowser:
return _BROWSER_MANAGER
async def warmup_md2img_browser(timeout_seconds: int = 45) -> bool:
"""预热 Markdown 转图浏览器(异步)。
设计目的:
1. 服务启动后提前完成浏览器冷启动,减少首个截图任务的等待和失败概率;
2. 不执行实际业务截图,仅确保常驻浏览器已可用。
"""
try:
manager = _get_browser_manager()
await asyncio.wait_for(manager.ensure_browser(), timeout=max(10, int(timeout_seconds)))
logger.info("[md2img] 浏览器预热完成")
return True
except Exception as e:
logger.error(f"[md2img] 浏览器预热失败: {e}")
return False
def warmup_md2img_browser_sync(timeout_seconds: int = 45) -> bool:
"""预热 Markdown 转图浏览器(同步包装,适合在线程中调用)。"""
try:
return asyncio.run(warmup_md2img_browser(timeout_seconds=timeout_seconds))
except Exception as e:
logger.error(f"[md2img] 同步预热执行失败: {e}")
return False
async def html_to_image(html_content, output_image):
manager = _get_browser_manager()
await manager.screenshot(html_content, output_image)