Skip to main content
设置 MCPHUB_REPLICA_MODE=true 显式启用多副本模式。相同版本的 MCPHub 通过负载均衡共享 PostgreSQL。MCP 2026 普通无状态调用可分发到任意就绪节点;旧协议会话、隔离上游客户端和 OpenAPI Cookie 状态仍属于单个进程,必须配置亲和性,节点故障后重新初始化。执行中的调用不迁移、不重放。

先准备数据库,再启动副本

所有节点设置 USE_DB=true 和同一 DB_URL,使用一致且持久的 JWT_SECRET(至少 32 字节)、MCPHUB_CREDENTIAL_ENCRYPTION_KEY(32 字节的 base64 编码)以及对外安装地址和 OAuth 地址。每个节点设置独立的 MCPHUB_NODE_ID,默认使用主机名。首次部署通过 ADMIN_PASSWORD 指定管理员密码。 构建后,先运行一个独立建库任务:
该任务复用现有数据库初始化和迁移流程,必要时创建管理员,并安装配置版本跟踪。升级已有数据库前先备份,避免多个建库任务并发执行。声明式 MCPHUB_SETTINGS_SYNC 仅在此任务中执行,接入节点必须取消该变量。 随后启动各副本:
接入节点启动时不创建扩展、不修改表结构、不重建向量索引。缺少数据库结构、管理员种子、持久密钥,或接入节点启用了声明式同步,都会阻止启动。stdio 服务器需要各节点具有一致的程序、环境和本地文件;子进程与文件系统状态不会自动共享。

使用 Docker 镜像部署

仓库的 examples/replicas/ 提供可直接使用的 Compose 示例,包含两个 MCPHub 副本、持久化 PostgreSQL、一次性建库任务和 Nginx。需要支持 --wait 的 Docker Compose v2,直接使用官方 samanhappy/mcphub 镜像。示例使用 latest,生产环境应将 MCPHUB_IMAGE 固定为已发布版本标签或 digest。
打开 http://localhost:3080,使用 admin 和 .env 中的 ADMIN_PASSWORD 登录。建库任务和两个副本始终使用同一镜像;node dist/db/setup.js 在容器内执行,宿主机无需安装 Node.js 或 pnpm。只读 settings.json 用于初始化空安装,默认关闭 OAuth 服务;启动后通过管理界面/API 管理共享配置。共享配置和凭据存入 PostgreSQL,不共用可写设置文件或 stdio 数据卷。 仅在验证未发布源码时,才需要在仓库根目录执行 docker build -t mcphub:replicas .,将 .env 中的镜像改为 MCPHUB_IMAGE=mcphub:replicas,并跳过该本地镜像的拉取。 网关仅绑定宿主机回环地址;对外部署时通过 HTTPS 入口暴露,并在首次建库前将 INSTALL_BASE_URL 改为实际 HTTPS 地址,确保所有节点使用相同的安装及 OAuth 对外地址。示例 Nginx 已配置流式响应、亲和性请求头及固定节点入口。Compose 健康检查仅控制首次启动顺序,Nginx 不主动轮询 /readyz,也不会自动摘除未就绪节点;生产流量入口需要单独实现。重建容器可能改变 IP,更新后端后应重建或重载 Nginx。此单机示例不提供宿主机、数据库或负载均衡自身的容灾。 已有安装应复用原数据库、JWT 密钥和凭据加密密钥,并在建库前备份数据库及密钥。升级应用时不要重新生成 .env 或顺便修改数据库密码。涉及表结构变更时先停止接流量和副本;本示例采用维护窗口,不假定所有结构变更都支持滚动升级:
建库失败时保持服务停止,先检查错误再继续。docker compose down 保留数据库命名卷;docker compose down -v 会删除它。不要将 .env 提交到版本库,数据库备份必须同时保留对应密钥。此 Compose 文件不会自动迁移已有文件模式安装,迁移时需要先将原设置文件及凭据 sidecar 挂载到建库任务中。

Kubernetes 部署

examples/kubernetes/replicas/ 提供独立建库 Job、双副本 Deployment、共享 ConfigMap、Service/Ingress 和 PodDisruptionBudget。默认使用官方 samanhappy/mcphub:latest 镜像;生产部署前,将 setup-job.yaml 和 deployment.yaml 两处镜像固定为同一版本或 digest。 先准备可访问且支持 pgvector 的 PostgreSQL,并为建库任务提供相应权限;数据库部署和备份不包含在清单中。对外暴露示例 Ingress 还需已有 Traefik 控制器、websecure 入口、DNS,以及 mcphub 命名空间中的 mcphub-tls TLS Secret。建库前,将 configmap.yaml 和 service.yaml 中的 mcphub.example.com 改为实际对外域名。只读初始配置不包含服务器,默认关闭 OAuth;建库后通过管理界面/API 管理共享配置。
仅在 Job 成功后继续。失败时先通过 kubectl -n mcphub logs job/mcphub-setup 排查,再创建接入 Pod;backoffLimit: 0 禁止自动重试表结构变更。同一时间只运行一个建库 Job,不要放进每个 Pod 的 init container。升级时复用数据库和共享密钥。首次管理员密码保存在 .env.local,仅建库 Job 接收该 Secret。妥善保存这两个本地密钥文件,并随数据库备份保留对应的 JWT/加密密钥。
启动和存活探针使用 /livez,就绪探针使用 /readyz,使数据库故障导致摘流,而非因存活检查触发重启。按上游需求调整十分钟启动预算和资源限制。节点标识取 Pod 名;调度器优先跨主机分散副本,宿主机冗余至少需要两个工作节点。PDB 在主动驱逐时保留一个副本,不能防止崩溃或显式缩容。preStop 等待五秒,让端点变化先传播,再接收 SIGTERM;30 秒退出宽限期包含该等待及 MCPHub 最多十秒的 HTTP 排空。应根据入口摘流耗时调整这些值,Pod 丢失仍会中断原会话。 示例使用 Traefik 的 Service Cookie 亲和性,直接路由到已就绪 Pod 端点。有状态客户端必须从初始化开始保存并回传 mcphub_affinity;Cookie 带 Secure 标记,因此必须使用 HTTPS。不能保留 Cookie 的客户端需另配控制器支持的稳定请求头路由或固定 Pod 入口。其他 Ingress 控制器需要替换对应亲和性配置,仅修改 ingressClassName 不够。不要为 MCP 请求添加响应缓冲或重试中间件,并按长连接需求配置控制器的请求/响应超时;这些清单不负责安装和配置控制器本身。 涉及表结构变更的升级,应先备份数据库、停止接入 Pod,并将两处镜像改为同一个新固定版本,在维护窗口内执行:
建库失败时保持副本停止。RollingUpdate 参数用于表结构及配置兼容时的镜像滚动更新,不代表任意表结构变更都能混跑。Kubernetes 不会共享 Pod 间的 stdio 进程、Cookie 状态或本地文件;集群、数据库及入口本身的高可用仍需部署方保障。

配置与授权

数据库触发器在配置写入的同一事务中递增版本,覆盖后台、CLI 和导入等入口。副本每 5 秒检查版本,刷新变化的服务器并保留未变化的连接。已应用版本表示配置已加载,不代表所有上游均已连接;上游连接失败单独报告为降级。 配置 API 读取响应包含 X-MCPHub-Config-Version 和 ETag。保存时携带读取到的 If-Match,版本过期返回 412。没有前置条件的并发写入仍会串行处理,等待期间版本改变返回 409;未提供 If-Match 时无法识别请求开始之前发生的修改。发生冲突后应重新读取并人工检查,不自动重提。失败的配置事务在响应前回滚。 工具调用独立于轮询,读取 PostgreSQL 中最新的服务器权限和启停状态;读取失败拒绝调用。OAuth 授权码和注册管理 token 共享存储、按哈希保存并检查过期,授权码原子消费。可能轮换 token 的 OAuth 客户端操作使用凭据范围的 PostgreSQL 互斥锁,过期写入通过条件更新拒绝。此类操作会占用额外连接,连接池应预留余量。 配置应用失败保留原已应用版本,就绪检查失败,后续轮询重试。数据库故障时也不接收新的工具调用,不提供离线授权模式。

负载均衡与状态

关闭 SSE 响应缓冲并设置足够长的超时,不为结果未知的工具调用开启代理重试。多副本模式关闭 MCPHub 的重连后工具重放和 OpenAPI 401 重放;上游协议自身仍可能执行认证处理。 从初始化开始使用稳定的工作流标识。参考 Nginx 配置使用 X-MCPHub-Affinity,缺省时使用 X-MCPHub-State-Id 进行一致性哈希。这些值只用于选节点,不参与身份验证。仅按 Mcp-Session-Id 哈希无法覆盖首次无会话握手。不能设置亲和性请求头的客户端可使用参考配置中的 /nodes/a/、/nodes/b/ 固定入口;节点故障后选择存活节点重新初始化。对外 OAuth 回调及资源地址保持使用安装地址。 现代通知订阅也属于单个节点。节点应用配置时向本地客户端广播变化;此版本不提供持久的跨节点上游通知总线,客户端重连后应重新发现能力。 响应通过 X-MCPHub-Node-Id、X-Request-Id 标识节点与请求;日志携带上下文,指标包含节点与配置版本。停机时停止接流量,等待 HTTP 请求最多 10 秒,再关闭上游客户端。编排器退出宽限期应超过 10 秒,并先摘流。超时的订阅连接断开后由客户端重连;断流不代表上游副作用未执行。

Docker 实测

脚本使用锁定依赖构建 Node 22 后端镜像,启动两个节点、PostgreSQL、Nginx 和受控 OpenAPI 上游,验证配置收敛、并发冲突、跨节点 OAuth、撤销、亲和性、断流不重放、停库、杀节点与排空,结束时清理容器和临时数据库。tests/docker/replicas/ 中的固定密码及 HTTP 地址仅供本机隔离测试。测试镜像不包含仪表盘、Python 和 uv;需要这些能力时使用项目正式 Dockerfile。 此版本不包含跨地域容灾、会话无损接管、工具恰好执行一次、独立控制面或本地状态共享。PostgreSQL 与负载均衡本身也需要独立的高可用安排。