composer默认http下载重试3次,但成败关键在单次请求耐受力:需协同调高http.timeout(或composer_network_timeout)与镜像源稳定性,二者缺一不可;--retries=5仅composer 2.2+有效且不作用于git clone。

Composer 没有“自动重试 N 次”的命令行开关,但它的 HTTP 下载层确实内置了默认 3 次重试逻辑;真正决定成败的不是重试次数,而是单次请求能不能活过网络抖动——这得靠 http.timeout、COMPOSER_NETWORK_TIMEOUT 和镜像源三者协同。
为什么 --retries=5 有时没用?
这个参数只在 Composer 2.2+ 中有效,且仅作用于 HTTP/HTTPS 包下载(zip/tar),对 git clone 完全无效。更关键的是:它不改变单次请求的等待上限。如果每次请求都在 60 秒内因 cURL error 28 超时,哪怕重试 10 次,结果还是秒败。
-
--retries控制“重试几轮”,http.timeout控制“每轮最多等多久”——二者必须一起调 - 旧版本(如 2.1.x)不识别
--retries,会静默忽略,命令照常执行但实际仍是默认 3 次 - 私有仓库未提供 dist 包时,Composer 自动 fallback 到 source,此时
--retries对 git 过程不起作用
怎么让单次 HTTP 请求扛过运营商 NAT 超时?
国内常见卡在 Downloading (0%),本质是 TLS 握手或首字节等待超时。默认 http.timeout=60 在高延迟链路上根本不够用。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 临时生效:
COMPOSER_NETWORK_TIMEOUT=300 composer install(单位秒,覆盖http.timeout) - 永久生效:
composer config -g http.timeout 300(注意:不是http-timeout,后者是旧别名) - 若仍失败,加
CURL_IPRESOLVE=4强制走 IPv4,避开某些 ISP 的 IPv6 不稳定问题
重试前必须清理哪些状态?
Composer 不会在重试时自动清理临时解压目录或部分写入的 zip 文件。残留损坏文件会导致下一次直接校验失败,报 file could not be downloaded: filemtime(): stat failed 等非网络类错误。
- CI 脚本中建议先
rm -rf vendor/ composer.lock再重试,比单纯composer install || sleep 5 && composer install更可靠 - 手动调试时,删掉
~/.composer/cache/files/下对应包的缓存目录,避免 Composer 复用已损坏的中间产物 - 不要依赖
--no-cache:它只跳过已缓存包,不清理已开始但失败的下载临时文件
镜像源配置后为什么还在连 packagist.org?
很多人执行了 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 就以为搞定了,但实际请求仍发往境外——因为项目级 composer.json 中的 repositories 字段会完全覆盖全局设置。
- 检查是否误在项目根目录
composer.json里写了:"repositories": [{"type": "composer", "url": "https://packagist.org"}] - 验证真实生效源:
composer config -g repos.packagist输出必须是镜像 URL,不是packagist.org或空对象 - 最稳妥的 CI 注入方式是环境变量:
COMPOSER_REPO_PACKAGIST=composer=https://mirrors.tuna.tsinghua.edu.cn/composer/
真正容易被忽略的点是:重试机制只管“下载是否完成”,不管“DNS 是否解析成功”或“TLS 握手是否卡住”。这些环节失败时,cURL 错误码(如 6、35、56)压根不会触发 Composer 层重试,必须靠镜像稳定性 + CURL_IPRESOLVE + 系统 DNS 缓存优化来兜底。










