Composer 2.0并行下载特性详解及如何进一步优化速度

10次阅读

composer 2.0 默认启用并行下载,速度提升2–3倍,但实际性能受网络、镜像源和磁盘I/O制约;盲目提高并发数(如设为8)易触发限流、I/O阻塞或内存不足,建议优先使用国内镜像、SSD缓存和–prefer-dist。

Composer 2.0并行下载特性详解及如何进一步优化速度

Composer 2.0 默认已启用并行下载,无需额外配置就能比 1.x 快 2–3 倍;但实际速度还高度依赖网络、镜像源和磁盘 I/O,盲目调高并发数反而可能触发限流或失败。

Composer 2.0 的并行下载是默认开启的,不是可选功能

从 Composer 2.0 开始,composer installcomposer update 默认使用多进程并发下载 ZIP 包(而非 1.x 的串行 curl),核心逻辑由 ParallelDownloader 类控制。它不依赖 pcntl 扩展,而是基于 phpstream_socket_client 异步非阻塞 I/O 实现。

  • 并发数默认为 4(可通过 COMPOSER_PROCESS_TIMEOUTCOMPOSER_PARALLEL 环境变量覆盖)
  • 每个并发连接独立处理一个包的 HEAD → GET 流程,失败后自动重试 3 次
  • 不适用于 path 类型仓库(本地路径)或启用了 "dist": false 的包(此时退化为 git 克隆)

为什么设置了 COMPOSER_PARALLEL=8 却更慢甚至报错?

提高并发数并不线性提升速度,尤其在以下场景会适得其反:

  • 国内直连 packagist.org 时,高并发易触发 Cloudflare 限流,返回 429 Too Many Requests
  • 磁盘写入慢(如机械硬盘或某些 docker volume)时,多个进程争抢写入 ZIP 导致 I/O 阻塞
  • PHP 内存限制不足(memory_limit),每个并发下载进程需额外 ~5–10MB 内存
  • 某些代理或企业防火墙对并发连接数做硬限制,超限直接断连

建议先用 COMPOSER_PARALLEL=2 测试稳定性,再逐步加到 46,超过 8 几乎无收益。

真正有效的提速组合:镜像 + 缓存 + 轻量 dist

相比调并发,这三项优化对国内用户效果更显著且稳定:

  • 换国内镜像源:composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
  • 启用本地缓存(Composer 2.0+ 默认开启):确保 COMPOSER_CACHE_DIR 指向 SSD 路径,避免挂载到网络存储
  • 强制走 dist(跳过 git clone):composer install --prefer-dist(默认行为,但 CI 中常被误覆盖为 --prefer-source

如果项目允许,还可删减开发依赖:用 composer install --no-dev 跳过 require-dev 包下载,通常减少 30%–50% 的请求量。

验证是否真的在并行下载

运行时加 -v 参数可看到并发痕迹,例如:

Downloading https://mirrors.aliyun.com/composer/p2/symfony/console.json (1.2 MB) Downloading https://mirrors.aliyun.com/composer/p2/phpunit/phpunit.json (1.8 MB) Downloading https://mirrors.aliyun.com/composer/p2/monolog/monolog.json (0.9 MB)

三行 Downloading... 同时出现即表示并行生效。若逐行打印、长时间卡在某一行,则大概率是镜像源响应慢或 dns 解析阻塞 —— 此时应检查 dig mirrors.aliyun.comcurl -I https://mirrors.aliyun.com/composer/ 是否正常。

并行下载只是 Composer 2.0 的基础能力,它的上限取决于你用的镜像有多快、磁盘写得多顺、以及有没有无意中关掉 --prefer-dist 或开了 debug 日志输出全路径 —— 这些细节比调并发数字重要得多。

text=ZqhQzanResources