Composer不支持自动fallback,多个同类型镜像源无效,必须通过脚本探测、动态切换和清缓存三步闭环实现容灾,且需显式禁用packagist.org。

Composer 本身不支持自动 fallback,所谓“下载失败时自动切备用镜像”是常见误解——它根本不会在 Downloading 失败后换源重试,只会报错退出。
为什么写多个 repositories 不起作用?
你在 composer.json 里写两个 {"type": "composer", "url": "..."},Composer 会直接报 Invalid repository type。因为它把 packagist.org 视为全局唯一元数据源,重复声明同类型就拒绝加载。即使侥幸绕过校验,它也只按顺序合并 packages.json,下载时固定从第一个提供该包版本信息的源拉取,不会因超时、503 或 DNS 失败而尝试下一个。
如何让备用镜像真正生效?
必须靠外部脚本探测 + 动态切换 + 清缓存三步闭环,缺一不可:
- 用
curl -I -s -o /dev/null -w "%{http_code}" https://mirrors.aliyun.com/composer/packages.json检查镜像根路径是否返回200 - 失败则换腾讯云:
curl -I -s -o /dev/null -w "%{http_code}" https://mirrors.cloud.tencent.com/composer/packages.json - 探测成功后执行
composer config -g repo.packagist composer https://xxx/(注意末尾斜杠和composer类型参数) -
必须紧接着运行
composer clear-cache,否则旧缓存里的packages.json还指向失效源
项目级配置比全局更可靠,但格式很关键
进项目根目录执行 composer config repo.packagist composer https://mirrors.aliyun.com/composer/(不加 -g),它会尝试合并进 composer.json 的 repositories 字段。但前提是原 repositories 是对象格式(如 "repositories": { "packagist": {} }),不是数组——否则命令直接失败。更隐蔽的是:如果 composer.json 根节点没写 "packagist.org": false,Composer 仍会先卡 30 秒请求官方源再 fallback,这个细节几乎没人检查。
真正容灾的关键不在“配几个源”,而在每次执行前确认当前生效源是否可用、缓存是否干净、packagist.org 是否被显式禁用——这三处任何一处出问题,备用逻辑就形同虚设。


















