composer不自动fallback或重试,镜像配置后仍连packagist.org主因是项目级repositories字段覆盖全局设置,需检查并清除该字段、清理缓存目录及设置http.timeout超时时间。

Composer 本身不 fallback、不重试、不测速,所谓“容错”不是它自带的能力,而是你必须手动补上的三道防线:配置防覆盖、缓存防中毒、请求防卡死。
为什么镜像配置后还在连 packagist.org
项目级 repositories 字段会完全覆盖全局设置,哪怕你执行了 composer config -g repo.packagist,只要 composer.json 里有 repositories(哪怕是空数组或只写了个私有源),Composer 就无视全局镜像,直连 packagist.org。
- 检查方法:
composer install -vvv | head -n 10,看第一行下载 URL 是不是镜像域名 - 临时验证:在项目根目录运行
composer config --unset repositories,再试安装 - 长期方案:若必须保留私有源,手动在
composer.json的repositories里加一条"packagist": { "type": "composer", "url": "https://mirrors.aliyun.com/composer/" },并在顶层加"packagist.org": false
缓存中毒导致集体卡死怎么清
composer clear-cache 不清元数据缓存,只清 ~/.composer/cache/files/ 和内存缓存;真正“中毒”的是 ~/.composer/cache/repo/https---mirrors-aliyun-com-composer/ 目录下的 packages.json 和 provider-*.json ——它们可能被 502/503 响应体污染,后续请求直接读坏文件,根本不发网络请求。
- 手动清理命令:
rm -rf $(composer config --global cache-dir)/repo/https---mirrors-aliyun-com-composer - Windows 用户需额外删:
%LOCALAPPDATA%\Composer\cache\repo\https---mirrors-aliyun-com-composer - CI 构建中建议加一步:
composer clear-cache && rm -rf $(composer config --global cache-dir)/repo/
弱网下如何让单次请求活过 NAT 超时
卡在 Downloading (0%) 多半是 TLS 握手或首字节等待超时,--retries=5 没用——它只控制重试次数,不延长单次等待时间。默认 http.timeout=60 在高延迟链路上根本不够。
- 临时生效:
COMPOSER_NETWORK_TIMEOUT=300 composer install - 永久生效:
composer config -g http.timeout 300(注意不是http-timeout) - IPv6 不稳定时加:
CURL_IPRESOLVE=4 composer install - 私有包没提供 dist 时,
--prefer-dist会 fallback 到 git clone,此时--retries完全失效,得靠 shell 封装兜底
真要容灾,得自己写 shell 封装
Composer 不支持多镜像 fallback,也不做指数退避。想应对抖动,唯一可靠方式是用 shell 控制流程:清状态 → 换源 → 等待 → 再试。
- 示例逻辑:
for i in {1..3}; do rm -rf vendor/ composer.lock; composer install --no-interaction --prefer-dist && break; sleep $((i * 10)); done - 每次失败必须删
vendor/和composer.lock,否则残留损坏文件会触发校验失败(如filemtime(): stat failed) - 别只写
composer install || sleep 5 && composer install——没清缓存和锁文件,大概率重复失败 - 镜像探测建议用
curl -I -m 5 https://mirrors.aliyun.com/composer/packages.json,响应码为 200 才认为可用
最易被忽略的点:镜像同步延迟(5–30 分钟)和元数据缓存过期策略(默认 15 分钟)共同作用,会让“刚换的源拉不到新包”看起来像网络故障——其实只是你查的 packages.json 还没更新,不是配置错了,也不是源挂了。











