diff --git a/app/api/qgis_map_export.py b/app/api/qgis_map_export.py index bf70911..4433972 100644 --- a/app/api/qgis_map_export.py +++ b/app/api/qgis_map_export.py @@ -20,7 +20,6 @@ from app.config.paths import get_logger from app.config.qgis_mappings import build_static_layers_config, get_gpkg_dir from app.repositories import qgis_repository from app.schemas.api_schemas import QgisMapExportResponse, QgisMapExportRequest -from app.utils.api_deps import get_prediction_semaphore from app.utils.db_helper import db_helper from config import settings @@ -179,18 +178,22 @@ def _build_qgis_config(batch_folder: str) -> dict: # 接口实现 # ============================================================ +# 全局并发限制 +import asyncio as _asyncio +_concurrent = getattr(settings, "QGIS_MAX_CONCURRENT", 2) +_qgis_semaphore = _asyncio.Semaphore(_concurrent) + + @router.post("/export/map", response_model=QgisMapExportResponse, summary="QGIS 批量专题图导出") async def export_map(req: QgisMapExportRequest): """ - 根据模拟ID批量导出专题图。同一 occurred_time 视为同一场灾害,共享文件夹 + 根据模拟ID批量导出专题图。同一 inferenceId 共享文件夹,增量产出缺失图片。 """ from app.services.qgis.qgis_env import is_qgis_available if not is_qgis_available(): - raise HTTPException(status_code=503, detail="QGIS 环境不可用(未找到 QGIS Python 3.12 解释器)") + raise HTTPException(status_code=503, detail="QGIS 环境不可用") - semaphore = get_prediction_semaphore() - - async with semaphore: + async with _qgis_semaphore: inference_id = req.inferenceId loop = asyncio.get_event_loop() diff --git a/settings.toml b/settings.toml index 904db54..cf2c308 100644 --- a/settings.toml +++ b/settings.toml @@ -21,6 +21,8 @@ QGIS_DEFAULTS_MAP_UNIT = "制图单位:西安市应急管理局" QGIS_EXPORT_DPI = 300 # 并行子进程数(每进程独立 QGIS 实例) QGIS_PARALLEL_WORKERS = 4 +# 最大并发请求数(防止多人同时触发资源耗尽) +QGIS_MAX_CONCURRENT = 2 # 优先产出模板 QGIS_PRIORITY_TEMPLATES = ["暴雨地质灾害风险区分布图", "暴雨滑坡潜在隐患点及人口分布图", "暴雨山洪潜在隐患点及人口分布图", "暴雨泥石流潜在隐患点及人口分布图", "暴雨内涝潜在隐患点及人口分布图", "暴雨避难场所分布图"]