Skip to main content

多副本、高可用和并发故障排除

本指南旨在解决在 多副本 环境(例如 Kubernetes、Docker Swarm)中部署 Open WebUI,或为了提高并发量而使用 多个 worker (UVICORN_WORKERS > 1) 时遇到的常见问题。

核心要求清单

在排查特定错误之前,请确保您的部署满足多副本设置的以下 绝对要求。缺少其中任何一项都会导致不稳定、登录循环或数据丢失。

  1. 共享密钥: WEBUI_SECRET_KEY 在所有副本上 必须 完全相同。
  2. 外部数据库:必须 使用外部 PostgreSQL 数据库(参见 DATABASE_URL)。多个实例 不支持 使用 SQLite。
  3. 用于 WebSocket 的 Redis: 需要设置 ENABLE_WEBSOCKET_SUPPORT=TrueWEBSOCKET_MANAGER=redis,并配有有效的 WEBSOCKET_REDIS_URL
  4. 共享存储: 持久卷(尽可能使用 RWX / ReadWriteMany,或确保所有副本都映射到相同的 data/ 底层存储)对于 RAG(上传/向量)和生成的图像至关重要。
  5. 外部向量数据库(推荐): 虽然嵌入式 Chroma 可以配合共享存储工作,但 强烈建议 使用专用的外部向量数据库(例如 PGVector、Milvus、Qdrant),以避免文件锁定问题并提高性能。

常见问题

1. 登录循环 / 401 Unauthorized 错误

症状:

  • 您成功登录,但下一次点击操作就会让您退出登录。
  • 登录后立即在浏览器控制台中看到“Unauthorized”或“401”错误。
  • 日志中出现“Error decrypting tokens”。

原因: 每个副本都使用了不同的 WEBUI_SECRET_KEY。当副本 A 发出会话令牌 (JWT) 时,副本 B 会拒绝它,因为它无法使用自己不同的密钥验证签名。

解决方案: 在所有后端副本上将 WEBUI_SECRET_KEY 环境变量设置为 同一个 强随机字符串。

# Kubernetes/Compose 示例
env:
- name: WEBUI_SECRET_KEY
value: "your-super-secure-static-key-here"

2. WebSocket 403 错误 / 连接失败

症状:

  • 聊天停止响应或挂起。
  • 浏览器控制台显示 WebSocket connection failed: 403 ForbiddenConnection closed
  • 日志显示 engineio.server: https://your-domain.com is not an accepted origin

原因:

  • CORS: 负载均衡器或 Ingress 的来源与允许的来源不匹配。
  • 缺少 Redis: WebSocket 默认为内存管理,因此副本 A 上的事件(例如 LLM 生成完成)无法广播给连接到副本 B 的用户。

解决方案:

  1. 配置 CORS: 确保 CORS_ALLOW_ORIGIN 包含了您的公共域名 以及 http/https 变体。

    如果您看到类似 engineio.base_server:_log_error_once:354 - https://yourdomain.com is not an accepted origin 的日志,则必须更新此变量。它接受 以分号分隔 的允许来源列表。

    示例:

    CORS_ALLOW_ORIGIN="https://chat.yourdomain.com;http://chat.yourdomain.com;https://yourhostname;http://localhost:3000"

    添加用户访问您的 Open WebUI 时可能使用的所有有效 IP、域名和主机名。

  2. 为 WebSocket 启用 Redis: 确保在 所有 副本上设置了以下变量:

    ENABLE_WEBSOCKET_SUPPORT=True
    WEBSOCKET_MANAGER=redis
    WEBSOCKET_REDIS_URL=redis://your-redis-host:6379/0

3. “未找到模型 (Model Not Found)” 或配置不匹配

症状:

  • 您在管理员界面启用了一个模型或更改了一个设置,但其他用户(或您在刷新页面后)看不到更改。
  • 聊天间歇性地失败,并提示“未找到模型”。

原因:

  • 配置同步: 副本之间未同步。Open WebUI 使用 Redis 发布/订阅 (Pub/Sub) 向所有其他实例广播配置更改(例如切换模型)。
  • 缺少 Redis: 如果未设置 REDIS_URL,配置更改将仅保留在进行更改的实例本地。

解决方案:REDIS_URL 设置为指向您的共享 Redis 实例。这将启用用于实时配置同步的发布/订阅机制。

REDIS_URL=redis://your-redis-host:6379/0

4. 数据库损坏 / “锁定 (Locked)” 错误

症状:

  • 日志显示 database is locked 或严重的 SQL 错误。
  • 在一个实例上保存的数据在另一个实例上消失了。

原因: 在多副本环境中使用 SQLite。SQLite 是基于文件的数据库,不支持来自多个容器的并发网络写入。

解决方案: 迁移到 PostgreSQL。更新您的连接字符串:

DATABASE_URL=postgresql://user:password@postgres-host:5432/dbname