Langflow 多 worker 部署下 worker 报 JobQueueNotFoundError 怎么排查?
【免费下载链接】langflowLangflow is a powerful tool for building and deploying AI-powered agents and workflows.项目地址: https://gitcode.com/GitHub_Trending/la/langflow
Langflow 默认以单个 worker 进程运行,build 任务状态保存在进程内存里。当你把LANGFLOW_WORKERS调到 1 以上做多 worker 部署时,每个进程各自持有独立的内存 build 队列;轮询和流式事件投递会在初始 build POST 之后发起后续的GET /api/v1/build/<job_id>/events请求,负载均衡器可能把这些请求路由到与发起 build 不同的 worker,而这个 worker 的队列里根本没有这个 job,于是 worker 间歇性报JobQueueNotFoundError。这篇文章只针对这一个错误:如何确认根因、如何修复、以及修复后怎么验证。
适用环境:同一台主机上运行多个 Langflow worker 进程的部署(Docker Compose 或裸机.env配置均可),文档以 Docker Compose 为例。
先理解根因,再开始检查
内存队列是 per-process 的,所以 worker A 上发起的 build 无法从 worker B 轮询或流式获取事件。Langflow 提供的解决方式是用 Redis 做共享 job 队列:把 build 事件写入 Redis Streams,任何 worker 都能拾取并服务任意 job 的事件。因此排查目标只有两个:
- 所有 worker 是否都启用了同一个共享队列(
LANGFLOW_JOB_QUEUE_TYPE=redis),且指向同一个 Redis 实例; - 队列配置本身有没有和缓存配置冲突。
下面按检查项逐项核对。
检查项 1:所有 worker 的LANGFLOW_JOB_QUEUE_TYPE是否都是redis
LANGFLOW_JOB_QUEUE_TYPE默认值是asyncio(即内存队列)。排查时确认每个 worker 进程的环境变量都是redis:
- 混合模式部署(部分 worker 用
asyncio、部分用redis)不受支持,必须全部一致。 - 如果是裸机部署,逐个进程查看其环境;如果是 Docker 部署,检查 compose 文件中
environment一节的LANGFLOW_JOB_QUEUE_TYPE。 - 注意:多 worker 且仍为
asyncio时,Langflow 会在启动阶段直接失败,报出解释"内存 job 队列是 worker 本地"的RuntimeError。如果你看到的是启动失败而不是运行时错误,根因同样是缺少共享队列,修复方式相同。
检查项 2:所有 worker 是否都能到达同一个 Redis 实例
确认各 worker 配置的 Redis 地址指向同一个实例,并区分两种配置形式:
LANGFLOW_REDIS_QUEUE_HOST/LANGFLOW_REDIS_QUEUE_PORT构造的是明文、未认证的连接,不支持认证和 TLS。- 如果 Redis 需要密码或 TLS(例如 AWS ElastiCache 开了 AUTH、Google MemoryStore 开了 TLS、Upstash 等托管服务),必须改用
LANGFLOW_REDIS_QUEUE_URL,例如rediss://user:password@host:6380/1。
如果 worker 报的是 Redis 连接被拒或认证错误,问题就出在这里:检查当前用的是不是 HOST/PORT 形式,改成 URL 形式。
检查项 3:缓存和队列是否共用了同一个 Redis 数据库索引
Langflow 缓存默认使用 DB0,job 队列默认使用 DB1。如果LANGFLOW_REDIS_QUEUE_DB被设置成了和缓存相同的数据库索引,两边的 key 会混在一起,产生不可预测的行为。核对两处配置指向不同的数据库索引。
修复:在所有 worker 上启用 Redis 队列
三项检查都确认后,在所有 worker 上设置以下环境变量并重启 Langflow:
LANGFLOW_WORKERS=3 # any value > 1 LANGFLOW_JOB_QUEUE_TYPE=redis LANGFLOW_REDIS_QUEUE_URL=redis://your-redis-host:6379/1其中your-redis-host替换为你的 Redis 主机地址(文档示例原样保留);URL 末尾的/1是队列使用的数据库索引,与缓存的 DB0区分开。
前提条件:Redis 6 或更高版本,且所有 worker 进程都能访问到。
如果还没有现成的多 worker 配置,可以参照 Deploy Langflow with multiple workers 中的 Docker Compose 示例,它定义了三个 Langflow worker 共享一个 Redis 队列和一个 PostgreSQL 数据库,关键配置为:
services: langflow: image: langflowai/langflow:1.10.0 pull_policy: always ports: - "7860:7860" depends_on: redis: condition: service_healthy postgres: condition: service_started environment: - LANGFLOW_DATABASE_URL=postgresql://langflow:langflow@postgres:5432/langflow - LANGFLOW_CONFIG_DIR=/app/langflow - LANGFLOW_WORKERS=3 # any value > 1 - LANGFLOW_GUNICORN_PRELOAD=true - LANGFLOW_JOB_QUEUE_TYPE=redis - LANGFLOW_REDIS_QUEUE_URL=redis://redis:6379/1 - LANGFLOW_SUPERUSER=admin - LANGFLOW_SUPERUSER_PASSWORD=changeme - LANGFLOW_AUTO_LOGIN=False volumes: - langflow-data:/app/langflow redis: image: redis:7-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 postgres: image: postgres:16-trixie environment: POSTGRES_USER: langflow POSTGRES_PASSWORD: langflow POSTGRES_DB: langflow volumes: - langflow-postgres:/var/lib/postgresql/data volumes: langflow-postgres: langflow-data:注意LANGFLOW_SUPERUSER/LANGFLOW_SUPERUSER_PASSWORD是示例中的超级管理员账号,实际部署请替换为自己的账号密码;运行该示例需要容器运行时至少 4 GB 内存和 2 CPU。
验证:确认队列真的切到了 Redis
1. 看启动日志
docker compose logs -f langflow文档给出的成功多 worker 启动日志片段(示例输出):
[preload] initializing services in master [preload] master preload complete; workers will inherit shared state via COW ✓ Launching Langflow...2. 查询 job 队列监控端点
先登录拿到 token(以下admin/changeme是 Compose 示例中的超级用户账号,替换为你实际设置的账号密码):
TOKEN=$(curl -s -X POST http://localhost:7860/api/v1/login \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=admin&password=changeme" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")然后查询monitor/job_queue端点(该端点需要超级用户认证,否则返回 HTTP 403):
curl -s -H "Authorization: Bearer $TOKEN" \ http://localhost:7860/api/v1/monitor/job_queue | python3 -m json.tool文档给出的 Redis 后端示例响应(数值为示例,不是固定预期):
{ "backend": "redis", "active_jobs": 0, "bridge_count": 0, "consumer_wrapper_count": 0, "background_task_count": 0, "cancel_dispatcher_running": true, "cancel_stats": { "published": 0, "marker_hit": 0, "dispatched_owned": 0, "dispatched_foreign": 0, "publish_errors": 0, "dispatcher_reconnects": 0, "dispatcher_internal_errors": 0, "polling_watchdog_kills": 0, "activity_touch_errors": 0, "activity_get_errors": 0, "activity_parse_errors": 0 } }判断依据:
"backend": "redis"确认队列已切到 Redis。内存(asyncio)后端只会返回backend和active_jobs两个字段。cancel_dispatcher_running: true确认该 worker 的跨 worker 取消通道已激活。若为false,该 worker 收不到跨 worker 取消信号;dispatcher 会以指数退避(上限 30 秒)自动重连,所以 Redis 重启期间短暂出现false是预期行为。
3. 触发一次真实 build 观察active_jobs
打开 Langflow UI,在Playground里给 flow 发一条消息触发 build,同时轮询monitor/job_queue端点。文档的验证方式是:active_jobs数值随之增加,即确认 Redis 队列正在工作。
与本报错相关的两个边界
- build 被意外取消:如果修复队列后仍有 build 被取消,可能是轮询看门狗把客户端心跳过期的 build 回收了。默认阈值 90 秒(
LANGFLOW_REDIS_QUEUE_POLLING_STALE_THRESHOLD_S=90);如果合法长任务被误杀,调大该值,或设为0彻底禁用看门狗。 cancel_stats.publish_errors持续非零:表示取消发布路径存在 Redis 连接问题,应回到检查项 2 复核 Redis 可达性。
更多配置项(LANGFLOW_REDIS_QUEUE_TTL、LANGFLOW_REDIS_QUEUE_STARTUP_GRACE_S、LANGFLOW_REDIS_QUEUE_CANCEL_CHANNEL_ENABLED等)及其默认值,见 配置参考表;其余多 worker 问题(Redis 认证错误、key 冲突、启动RuntimeError)的完整条目见 Troubleshoot Langflow 的 Multi-worker deployments 章节。
【免费下载链接】langflowLangflow is a powerful tool for building and deploying AI-powered agents and workflows.项目地址: https://gitcode.com/GitHub_Trending/la/langflow
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考