composer install 默认不并行是因为仅 2.2+ 版本原生支持,且仅在 composer.lock 存在时对 install 生效,依赖 curl 的 curl_multi、合规仓库响应及本地缓存干净。

composer install 为什么默认不并行
因为 Composer 2.2+ 才原生支持并行下载,且仅对 composer install(非 update)生效,前提是所有包都已锁定在 composer.lock 中。它不是靠开多线程“硬并发”,而是复用已建立的 HTTP 连接池 + 并行触发多个包的元数据解析与 ZIP 下载,本质是减少网络等待时间。
- 没锁版本(比如删了
composer.lock或运行composer update)时,--parallel会被自动忽略 - PHP 的 cURL 扩展必须启用
curl_multi,否则降级为串行(不会报错,但没提速效果) - 某些自定义仓库(如私有 Satis、Artifactory)若未正确响应
Accept: application/json或返回非标准 JSON,会导致部分包跳过并行流程
怎么启用并行安装:命令与配置项
最直接的方式是在命令行加 --parallel 参数:
composer install --parallel
也可以设为全局默认(写入 COMPOSER_HOME/config.json):
{
"config": {
"parallel": true
}
}
-
--parallel等价于--parallel=4,默认最多 4 个并发连接;可显式指定数字,如--parallel=6 - 并发数不是越多越好:超过 8 容易触发 GitHub API 限流(返回
403 rate limit exceeded),也容易占满本地 DNS 缓存或小带宽出口 - 该参数只影响下载阶段,autoload 生成、脚本执行等仍为串行
哪些情况并行会失效或变慢
看似开了 --parallel,但实际没提速,常见于以下场景:
- 本地
vendor/已存在,且所有包版本匹配composer.lock→ Composer 直接跳过下载,自然无并行可言 - 启用了
apcu或opcache.enable_cli=1,但 APCu 缓存被污染(如多次composer dump-autoload后未清理),导致元数据解析卡在单点 - 使用
https://packagist.org以外的源,而该源不支持并发请求(例如某些老旧的 Satis 实例返回 302 跳转而非直接提供 ZIP URL) - 磁盘 I/O 瓶颈:在机械硬盘或 NFS 挂载卷上解压大量小 ZIP 包时,并行反而加剧寻道竞争
验证是否真正在并行工作
加 -v(verbose)看日志里有没有类似这样的输出:
Downloading https://api.github.com/repos/symfony/console/zipball/... (1.2 MB) Downloading https://api.github.com/repos/doctrine/inflector/zipball/... (32 KB)
如果两行下载地址几乎同时出现,说明并行生效;如果严格按顺序打印,大概率被降级了。
- 注意区分
Downloading(真正发请求)和Writing(写入 vendor)——后者永远串行 - 用
strace -e trace=connect,sendto,recvfrom php composer.phar install --parallel -v 2>&1 | grep 'connect\|sendto' | head -10可粗略观察并发连接行为(Linux/macOS) - Windows 上可用 Process Monitor 过滤
php.exe的 TCP 连接事件
并行不是银弹,它依赖稳定的网络、合规的源服务、干净的本地缓存,以及一个没被 opcache 错误缓存住的 Composer 自身。调得过猛,反而触发 API 限流或 DNS 超时,这时候关掉 --parallel 可能更快。










