satis 本身不支持高可用集群,需通过静态文件+基础设施层(如共享存储、健康检查nginx、一致客户端配置)实现。其 build 为一次性进程,无状态、无健康接口,多节点需共享存储确保 packages.json 与 zip url 一致,并严格校验原子发布与配置对齐。

Satis 本身不能做高可用集群,所谓“高可用”是静态文件 + 基础设施层的组合方案,不是给 satis build 加节点就能解决的。
为什么 satis build 不能直接上负载均衡
Satis 是纯静态生成器:不监听端口、不连数据库、不处理并发请求。它只输出 packages.json 和 dist/ 下的 ZIP 包,没有状态可同步,也没有健康检查接口可探活。
- 你无法对
satis build进程做健康探测——它执行完就退出,不是常驻服务 - 多个
satis build并行跑在不同机器上,若没共享存储,packages.json里写的dist.url会指向本地路径,其他节点根本找不到 ZIP 文件 - CI/CD 触发重建时,若只推到一台 Nginx,其余节点还是旧文件,
composer install就卡在Downloading (connecting)
Nginx 负载均衡必须配健康检查 + 共享存储
所有 Web 节点必须托管完全一致的静态文件,否则 packages.json 和实际 ZIP URL 对不上,下游必失败。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- Web 节点的
root必须指向同一份文件——用 NFS、MinIO 或 S3 挂载,不能靠 rsync 同步(有窗口期不一致) - Nginx upstream 必须启用
health_check,例如:health_check interval=3 fails=2 passes=2;,否则宕机节点仍被轮询 - 确保每个节点都能
GET https://mirror.example.com/packages.json返回 200,且内容一致;404 或 HTML 欢迎页说明 Nginx 配置错位 - HTTP 响应头需加
Cache-Control: public, max-age=3600,避免客户端反复拉取元数据
客户端 composer.json 必须禁用官方源并显式声明顺序
私有源写错位置或没关 packagist.org,会导致同名包从官方拉取,覆盖你的私有版本。
-
repositories必须是根级字段,不能嵌套在require或其他字段下 - URL 必须和
satis.json中的homepage完全一致,包括末尾斜杠:"https://packages.internal/"≠"https://packages.internal" - 务必加
"packagist.org": false,否则 Composer 会默认启用官方源,且优先级高于私有源 - 私有源放
repositories数组第一位,Composer 不合并同名包,只取第一个匹配项
CI/CD 自动发布必须原子更新 + 版本校验
构建完成就直接 rsync 到线上?这是最常见导致半截文件上线的坑。
- 先在临时目录
build-$(date +%s)下完整生成web/,再用mv原子替换旧目录,避免中间态 - 构建后加校验:对比新旧
packages.json的sha256sum,若不变则跳过发布,防止无效 rebuild 冲刷缓存 - dist ZIP 文件上传到对象存储后,要验证
curl -I https://packages.internal/dist/xxx.zip返回 200,再更新packages.json中的 URL - CI 中设
COMPOSER_MIRROR_PATH_REPOS=1环境变量,让 Composer 在失败时自动 fallback 到下一个仓库
真正难的不是部署几台 Nginx,而是让所有节点的 packages.json、ZIP 文件、Nginx 配置、客户端配置四者严格对齐——漏掉任意一环,composer install 就会在某个随机时间点静默失败。










