composer不支持指数退避,其--retries仅控制dist包下载重试次数且不延长单次超时,需结合composer_network_timeout调优、shell封装实现指数退避及镜像源主动探测才能应对弱网抖动。

Composer 本身不支持指数退避,它的 HTTP 重试是固定延迟、最多 3 次;真要扛住极端抖动,得绕过默认逻辑,用 shell 封装 + 环境变量调优 + 镜像源兜底三者协同。
为什么 --retries=5 在弱网下经常失效
这个参数只在 Composer 2.2+ 生效,且仅作用于 dist 包(zip/tar)下载,对 git clone 完全无效。更关键的是:它不延长单次请求的等待时间——如果每次都在 CURL error 28(超时)下失败,重试 10 次也还是秒败。
-
--retries控制“重试轮数”,http.timeout或COMPOSER_NETWORK_TIMEOUT才决定“每轮能忍多久” - 旧版本(如 2.1.x)会静默忽略
--retries,实际仍是默认 3 次 - 私有包没提供 dist 时,Composer 自动 fallback 到 source,此时
--retries不起作用
怎么让单次 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 不稳定问题
shell 封装才是最可控的“指数退避”方案
Composer 没内置指数退避,但你可以用 shell 实现:每次失败后清状态、等更久、再试。这比依赖它自身逻辑可靠得多。
- CI 脚本中推荐写法:
for i in {1..3}; do rm -rf vendor/ composer.lock composer install --no-interaction --prefer-dist && break sleep $((i * 10)) done -
--prefer-dist强制走 zip 包,跳过易被拦截的git clone - 每次失败都
rm -rf vendor/ composer.lock,避免残留损坏文件导致下一次校验失败(比如filemtime(): stat failed) - 不要只靠
composer install || sleep 5 && composer install—— 没清缓存和临时文件,大概率重复失败
镜像源配置后还在连 packagist.org?这是个常见误解
Composer 的 repositories 数组不是容灾列表,而是元数据匹配顺序表。它不会因为第一个源超时就自动切到第二个。
- 只有当首个源对某包返回明确
404,才会查下一个源是否声明了该包 -
timeout、502、503、DNS 失败等,直接报错退出,绝不会 fallback - 想实现主备切换,必须外部探测:
curl -I -s -o /dev/null -w "%{http_code}" https://mirrors.aliyun.com/composer/packages.json,只认200,再动态执行composer config --global repo.packagist composer https://xxx.com/composer/
真正难的不是写几行重试代码,而是理解 Composer 的重试边界在哪——它只管 HTTP 下载层,不管 DNS、TLS、git、缓存损坏、镜像可用性。这些都得你手动补位,漏掉任何一环,重试就只是“反复失败”。










