多副本、高可用和并发故障排除
本指南旨在解决在 多副本 环境(例如 Kubernetes、Docker Swarm)中部署 Open WebUI,或为了提高并发量而使用 多个 worker (UVICORN_WORKERS > 1) 时遇到的常见问题。
核心要求清单
在排查特定错误之前,请确保您的部署满足多副本设置的以下 绝对要求。缺少其中任何一项都会导致不稳定、登录循环或数据丢失。
- 共享密钥:
WEBUI_SECRET_KEY在所有副本上 必须 完全相同。 - 外部数据库: 您 必须 使用外部 PostgreSQL 数据库(参见
DATABASE_URL)。多个实例 不支持 使用 SQLite。 - 用于 WebSocket 的 Redis: 需要设置
ENABLE_WEBSOCKET_SUPPORT=True和WEBSOCKET_MANAGER=redis,并配有有效的WEBSOCKET_REDIS_URL。 - 共享存储: 持久卷(尽可能使用 RWX / ReadWriteMany,或确保所有副本都映射到相同的
data/底层存储)对于 RAG(上传/向量)和生成的图像至关重要。 - 外部向量数据库(推荐): 虽然嵌入式 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 Forbidden或Connection closed。 - 日志显示
engineio.server: https://your-domain.com is not an accepted origin。
原因:
- CORS: 负载均衡器或 Ingress 的来源与允许的来源不匹配。
- 缺少 Redis: WebSocket 默认为内存管理,因此副本 A 上的事件(例如 LLM 生成完成)无法广播给连接到副本 B 的用户。
解决方案:
-
配置 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、域名和主机名。
-
为 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