SurfSense zero-cache 报 "Insufficient upstream connections" 怎么排查?
【免费下载链接】SurfSenseOpen-source NotebookLM alternative. Research the open web with live data(Reddit, YT, IG, TikTok, Indeed, Google Search, Maps etc) through one platform, API or MCP server. Join our Discord: https://discord.gg/ejRNvftDp9项目地址: https://gitcode.com/GitHub_Trending/su/SurfSense
在 SurfSense 的 Docker 部署中,如果 zero-cache(Rocicorp Zero 的实时同步服务,负责把 PostgreSQL 变更经逻辑复制推给浏览器)在日志里反复报Insufficient upstream connections,说明它的 view-sync worker 数量超过了数据库连接池上限。官方文档给出的根因是:zero-cache 会把ZERO_NUM_SYNC_WORKERS默认取为 CPU 核心数,在高核心数机器上这个数字可能超过连接池限制。修复方式是在.env中调低ZERO_NUM_SYNC_WORKERS,或调高ZERO_UPSTREAM_MAX_CONNS/ZERO_CVR_MAX_CONNS,然后重启 compose 栈。
先确认错误与适用前提
适用环境:SurfSense 通过 Docker 部署(一键安装脚本或手动 clone 后docker compose启动),zero-cache 使用rocicorp/zero:1.6.0镜像,随 compose 文件 docker-compose.yml 启动。
在部署目录下查看 zero-cache 日志,确认错误现象:
docker compose logs zero-cache安装脚本创建的部署目录是surfsense/(命令需在该目录内执行);手动 clone 的部署目录是docker/。
在排查连接池问题之前,先排除文档中列出的其他 zero-cache 故障形态,它们的现象和根因都不同:
Unknown or invalid publications. Specified: [zero_publication]:zero-cache 先于 migrations 启动,不是连接池问题(见 Docker 安装文档的 Troubleshooting 章节);_zero.tableMetadata崩溃:上次运行留下了半初始化的 SQLite replica,需要清理卷后重建;- 容器起不来但报的是
wal_level相关错误:PostgreSQL 未开启逻辑复制(wal_level=logical)。
如果你看到的正是Insufficient upstream connections,按下面两条路径处理。
三个相关参数及其约束
以下定义来自 Real-Time Sync with Zero 的配置表:
| 变量 | 说明 | SurfSense compose 默认值 |
|---|---|---|
ZERO_NUM_SYNC_WORKERS | view-sync worker 进程数,必须 ≤ZERO_UPSTREAM_MAX_CONNS且 ≤ZERO_CVR_MAX_CONNS | 4 |
ZERO_UPSTREAM_MAX_CONNS | 到上游 PostgreSQL 用于 mutations 的最大连接数 | 20 |
ZERO_CVR_MAX_CONNS | 到 CVR 数据库的最大连接数 | 30 |
三个参数之间的约束是硬性要求:ZERO_NUM_SYNC_WORKERS不得超过另外两个值。compose 文件里三者都通过${VAR:-默认值}形式从.env读取,因此直接改.env即可,无需改 compose 文件本身。
修改 .env 中的连接配置
.env的位置取决于部署方式:
- 一键安装脚本:
surfsense/.env - 手动 clone +
docker compose:docker/.env - 贡献者开发栈(
docker-compose.dev.yml):变量同样从docker/.env读取
两种改法任选其一,文档原话是 "LowerZERO_NUM_SYNC_WORKERSor raiseZERO_UPSTREAM_MAX_CONNS/ZERO_CVR_MAX_CONNSin your.env":
方案一:调低 worker 数(连接数保持默认时通常够用):
ZERO_NUM_SYNC_WORKERS=4方案二:调高连接池上限,保留更多 worker(示例值,需自行按机器情况取值):
ZERO_UPSTREAM_MAX_CONNS=40 ZERO_CVR_MAX_CONNS=40采用方案二时务必同时检查约束:ZERO_NUM_SYNC_WORKERS仍必须 ≤ 这两个新值,否则改完不会生效。文档没有给出推荐的具体数值,只给出了约束关系,取值时以你的 CPU 核心数和 PostgreSQL 连接能力为准。
应用配置并验证
修改.env后重启栈(Docker 安装文档中的标准操作):
docker compose up -d按顺序验证:
看日志不再报错:
docker compose logs zero-cacheInsufficient upstream connections不再出现。确认服务转为 healthy:
docker compose ps中 zero-cache 从(health: starting)变为(healthy)。该服务内置的 healthcheck 就是对容器内http://localhost:4848/keepalive执行curl -f,所以 healthy 状态本身就说明 keepalive 检查通过了。端口已发布时的直接探活:在手动安装或开发栈中 zero-cache 会发布
4848端口,可以直接验证(来自 Manual Installation 的验证方式):curl http://localhost:4848/keepalive # 应返回 HTTP 200前端实时同步恢复:打开浏览器确认通知、上传状态等不再需要手动刷新;如果仍不同步,打开 DevTools → Console 检查 WebSocket 连接错误(生产栈中
/zero/*由 Caddy 转发到内部zero-cache:4848)。
修复后仍异常时的边界
- 大库重启后短暂 stale 属于已知现象:zero-cache 启动时会从 PostgreSQL 重建 SQLite replica,数据库较大时"需要一点时间"(原文:This may take a moment for large databases)。在重建期间前端可能读到旧数据,属正常现象,不必当作新故障。
/statz端点需要管理员密码:zero-cache 的 admin UI 和/statz端点受ZERO_ADMIN_PASSWORD保护,默认值为surfsense-zero-admin,在浏览器或 curl 访问时带上该密码即可查看运行状态。- 不要把本错误的排查路径套用到其他日志上:
Unknown or invalid publications的恢复是docker compose down+docker volume rm surfsense-zero-cache+docker compose up -d;_zero.tableMetadata崩溃则需要删容器并删卷后重跑 zero-cache 启动命令。这两类问题的文档恢复步骤都会销毁 zero-cache 数据卷,在确认错误类型之前不要执行。
【免费下载链接】SurfSenseOpen-source NotebookLM alternative. Research the open web with live data(Reddit, YT, IG, TikTok, Indeed, Google Search, Maps etc) through one platform, API or MCP server. Join our Discord: https://discord.gg/ejRNvftDp9项目地址: https://gitcode.com/GitHub_Trending/su/SurfSense
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考