Files
insar-management-system-v2/docs/LANDSAR_CLUSTER_WORKER_DEPLOYMENT_20260624.md

363 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LandSAR 集群 Worker 设计与部署记录(2026-06-24
## 结论
本次改造是在保留本机 LandSAR 生产链路的前提下,新增 LandSAR 集群执行入口。
本机旧入口仍然是 `LANDSAR_RUN`:由主服务器上的一个控制器串行处理一个批次内的 pair。新入口是 `LANDSAR_CLUSTER_ITEM`:主服务器提交集群任务后,系统按 pair 拆成多条队列任务,由本机或远端 Windows worker 领取执行。
当前规划的远端计算服务器是:
- 主服务器 / PostgreSQL / Web 系统:`192.168.1.62`
- 远端 LandSAR worker`192.168.1.6`
远端 worker 的 `.env``DATABASE_URL` 必须指向主服务器 `192.168.1.62`,不是写它自己 `192.168.1.6`
## 已落地代码
后端集群入口:
- `backend/app/routers/dinsar_production.py`
- 新增 `POST /dinsar-production/landsar-cluster/run`
- 只接受 `engine_code=landsar`
- 提交后按 Task/pair 拆分为多个 `LANDSAR_CLUSTER_ITEM`
生产服务:
- `backend/app/services/dinsar_production_service.py`
- 新增 `create_landsar_cluster_run`
- 复用现有 `DinsarProductionRunORM``DinsarProductionRunItemORM``DinsarProductionExecutionORM`
- 不新增 PG 表结构
- 新增 `LANDSAR_CLUSTER_RUN` 父任务类型
队列与 worker
- `backend/app/services/job_queue_service.py`
- `claim_next_job` 支持 `allowed_job_types`
- `backend/app/services/job_worker.py`
- 新增 `JOB_WORKER_ALLOWED_TYPES` 过滤
- 远端 worker 可配置为只领取 `LANDSAR_CLUSTER_ITEM`
- `backend/app/services/job_handlers.py`
- 新增 `LANDSAR_CLUSTER_ITEM` handler
- 每个 handler 只处理一个 pair
- 使用本进程本地锁避免单台机器上多个 LandSAR 任务并发抢授权
- 不使用旧 `wsl_dinsar_landsar` 全局数据库锁,因此多台服务器可以并行处理不同 pair
远端专用入口:
- `run_landsar_cluster_worker.py`
- Windows 远端直接运行此脚本即可
- 默认只领取 `LANDSAR_CLUSTER_ITEM`
- 默认并发为 1
- `scripts/start_landsar_cluster_worker.ps1`
- 远端 Windows 推荐启动器
- 检查 `.env`
- 自动定位 Python
- 创建 `logs\landsar_cluster_worker`
- 支持前台运行和 `-Background` 后台运行
- `scripts/start_landsar_cluster_worker.bat`
- 远端双击启动入口,内部调用 PowerShell 启动器
- `scripts/stop_landsar_cluster_worker.ps1`
- 停止后台 worker,默认使用 `runtime\landsar_cluster_worker\worker.pid`
-`-All` 可清理所有命令行包含 `run_landsar_cluster_worker.py` 的 Python worker
- `scripts/stop_landsar_cluster_worker.bat`
- 远端双击停止入口,内部调用 PowerShell 停止脚本
主服务器网络准入脚本:
- `scripts/sync_landsar_cluster_network_access.ps1`
- 从主服务器 `.env` 读取 `LANDSAR_CLUSTER_ALLOWED_WORKER_IPS`
- 同步 PostgreSQL `pg_hba.conf`
- 同步 Windows 防火墙 TCP `5432`
- reload PostgreSQL
前端入口:
- `frontend/src/DinsarProductionPanel.jsx`
- LandSAR 引擎下新增“提交 LandSAR 集群”按钮
- 原“提交任务”按钮仍走本机旧链路
## 主服务器配置
主服务器 `.env` 增加:
```env
LANDSAR_CLUSTER_ALLOWED_WORKER_IPS=192.168.1.6
```
如果后续增加更多 worker,用逗号或分号分隔:
```env
LANDSAR_CLUSTER_ALLOWED_WORKER_IPS=192.168.1.6,192.168.1.7,192.168.1.8
```
每次修改后在主服务器执行:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\sync_landsar_cluster_network_access.ps1
```
脚本会把允许的 worker IP 写入 `D:\PostgreSQLData\pg_hba.conf` 的受管控区块:
```text
# BEGIN InSAR LandSAR cluster workers
host insar_management all 192.168.1.6/32 scram-sha-256
# END InSAR LandSAR cluster workers
```
同时维护 Windows 防火墙规则:
```text
InSAR PostgreSQL 5432 LandSAR Cluster
```
当前主服务器已完成配置:
- PostgreSQL 监听 `0.0.0.0:5432`
- `pg_hba.conf` 只允许 `192.168.1.6/32` 访问 `insar_management`
- 防火墙 TCP `5432` 只允许 `192.168.1.6`
## 远端 192.168.1.6 需要复制什么
推荐复制整个当前仓库,而不是只挑脚本。
原因是远端 worker 虽然只运行 `run_landsar_cluster_worker.py`,但它会 import 后端配置、ORM、队列服务、LandSAR engine、结果发布服务、任务服务等模块。只复制单个脚本会缺依赖。
建议远端目录保持一致:
```text
D:\Code\Insar_management_system_v2
```
至少要确保这些内容在远端存在并与主服务器代码版本一致:
- `run_landsar_cluster_worker.py`
- `backend/`
- `scripts/`
- `config/`
- `.env`
- Python 依赖环境
- LandSAR 安装目录
- DEM 文件
- 任务输入目录或可访问的任务输入路径
- 结果返回目录或可访问的结果目录
前端 `frontend/` 对远端 worker 不是运行必需,但为了版本一致,建议整仓同步。
## 远端 192.168.1.6 的 .env
远端 `.env` 模板已维护在:
```text
config\landsar_cluster_worker.env.example
```
复制为远端项目根目录 `.env`
```powershell
Copy-Item config\landsar_cluster_worker.env.example .env
```
远端 `.env` 的核心配置:
```env
DATABASE_URL=postgresql+asyncpg://postgres:WXZXzhb123456@192.168.1.62:5432/insar_management
JOB_WORKER_ALLOWED_TYPES=LANDSAR_CLUSTER_ITEM
JOB_WORKER_CONCURRENCY=1
JOB_WORKER_POLL_INTERVAL=1.0
LANDSAR_CLUSTER_WORKER_ID=
```
还需要按远端实际 LandSAR 环境配置这些项:
```env
LANDSAR_ENABLED=true
LANDSAR_HOME=D:\LandSAR
LANDSAR_CONSOLE_EXE=D:\LandSAR\InSAR_Console.exe
LANDSAR_WORK_ROOT=D:\LandSAR_Work
LANDSAR_RUNTIME_PATHS=D:\LandSAR
LANDSAR_LICENSE_MODE=netVersion
LANDSAR_LICENSE_HOST=127.0.0.1
LANDSAR_LICENSE_PORT=6666
LANDSAR_CONFIG_ROW=netVersion,zh,127.0.0.1,6666
LANDSAR_CONFIG_AUTO_WRITE=true
LANDSAR_AUTH_SERVER_EXE=D:\Code\Insar_management_system_v2\third_party\LandSAR\tools\_portable_release\LandSAR_auth_tools_win64\landsar_net_auth_server.exe
LANDSAR_AUTH_SERVER_AUTO_START=true
LANDSAR_AUTH_SERVER_HOST=127.0.0.1
LANDSAR_AUTH_SERVER_PORT=6666
LANDSAR_DEM_PATH=D:\DEM\SRTMDEM_RSP_SARscape_global_int16.tif
LANDSAR_DINSAR_TIMEOUT_SECONDS=43200
```
如果远端的 LandSAR 授权服务器、安装路径、DEM 路径不同,按远端实际路径填写。
建议给 `LANDSAR_CLUSTER_WORKER_ID` 一个稳定值,方便主服务器健康检查区分节点:
```env
LANDSAR_CLUSTER_WORKER_ID=landsar-worker-192-168-1-6
```
## 远端 Windows 启动命令
`192.168.1.6` 上进入项目目录:
```powershell
Set-Location D:\Code\Insar_management_system_v2
```
启动 worker
```powershell
.\scripts\start_landsar_cluster_worker.ps1
```
看到类似输出即表示监听程序已启动:
```text
[*] Starting LandSAR cluster worker...
[*] Allowed job types: LANDSAR_CLUSTER_ITEM
[*] Poll interval: 1s
[*] Concurrency: 1
```
需要双击启动时,运行:
```text
D:\Code\Insar_management_system_v2\scripts\start_landsar_cluster_worker.bat
```
需要后台启动时,运行:
```powershell
.\scripts\start_landsar_cluster_worker.ps1 -Background
```
后台停止:
```powershell
.\scripts\stop_landsar_cluster_worker.ps1
```
如果需要强制清理全部 LandSAR cluster worker
```powershell
.\scripts\stop_landsar_cluster_worker.ps1 -All
```
需要双击停止时,运行:
```text
D:\Code\Insar_management_system_v2\scripts\stop_landsar_cluster_worker.bat
```
启动日志在:
```text
D:\Code\Insar_management_system_v2\logs\landsar_cluster_worker
```
后台 worker PID 文件在:
```text
D:\Code\Insar_management_system_v2\runtime\landsar_cluster_worker\worker.pid
```
## 远端连通性检查
`192.168.1.6` 上检查能否连主服务器数据库:
```powershell
Test-NetConnection 192.168.1.62 -Port 5432
```
应看到:
```text
TcpTestSucceeded : True
```
再用 Python 检查数据库认证:
```powershell
$env:DATABASE_URL='postgresql+asyncpg://postgres:WXZXzhb123456@192.168.1.62:5432/insar_management'
@'
import asyncio, os
from sqlalchemy import text
from sqlalchemy.ext.asyncio import create_async_engine
async def main():
engine = create_async_engine(os.environ["DATABASE_URL"], pool_pre_ping=True)
async with engine.connect() as conn:
print((await conn.execute(text("select 1"))).scalar_one())
await engine.dispose()
asyncio.run(main())
'@ | C:\ProgramData\anaconda3\envs\InSAR\python.exe -
```
应输出:
```text
1
```
## 生产使用流程
1. 主服务器前端进入 D-InSAR 生产管理。
2. 选择 LandSAR 引擎。
3. 选择生产根目录,例如 `D:\Task_Pool\DInSAR` 或某个具体 `Task_*` 父目录。
4. 点击“提交 LandSAR 集群”。
5. 后端创建一个 `LANDSAR_CLUSTER_RUN` 父任务。
6. 每个 pair 生成一条 `LANDSAR_CLUSTER_ITEM` 队列任务。
7. 本机或远端 worker 抢占 item。
8. worker 调用本机 LandSAR 环境处理该 pair。
9. item 完成后写 execution manifest,并尝试发布到 D-InSAR 结果 catalog。
10. 所有 item 进入终态后,父 run 标记为完成、失败或取消。
## 当前重要约束
这次改造解决的是“按 pair 分片调度和多 worker 领取”的问题,不是完整的数据自动搬运系统。
因此远端 `192.168.1.6` 必须满足以下路径条件之一:
1. 与主服务器保持相同盘符和目录结构,并能看到同样的 `Task_Pool` 输入数据。
2. 或者远端通过映射盘、同步工具、计划任务等方式,把所需 pair 的输入数据准备到相同路径。
3. 结果输出目录也必须让主服务器可以扫描或访问,否则 worker 虽然能计算,结果不会自然回到主服务器 catalog。
当前代码中的 LandSAR cluster item 使用数据库里已有的 `source_task_dir` 作为 LandSAR 输入目录;它不会自动从源压缩包解包到远端,也不会自动把远端本地结果复制回主服务器。
后续若要彻底工程化,应新增两个能力:
- 集群 item 开始前:按 pair 从源压缩包或主服务器 Task_Pool materialize 到远端本地工作目录。
- 集群 item 完成后:把标准产品包从远端回传到主服务器结果目录,再由主服务器统一入库。
## 不要混淆的 IP
`192.168.1.62` 是主服务器 IP,负责:
- Web 后端
- PostgreSQL
- 任务队列
- 数据库自维护
- 前端操作入口
`192.168.1.6` 是远端 LandSAR worker IP,负责:
- 常驻监听 `LANDSAR_CLUSTER_ITEM`
- 调用本机 LandSAR
- 写 item 执行状态
所以远端 `.env` 中:
```env
DATABASE_URL=...@192.168.1.62:5432/insar_management
```
而主服务器 `.env` 中:
```env
LANDSAR_CLUSTER_ALLOWED_WORKER_IPS=192.168.1.6
```
这两个配置方向不同,不能互换。