composer默认并发数理论为12,但受curl句柄池、dns解析和文件描述符限制(如linux默认ulimit -n 1024)影响,实际并发常更低;调高并发易触发超时重试雪崩,优先优化镜像源、缓存和锁文件复用更有效。

Composer默认并发数是12,但实际受限于cURL句柄和DNS解析
Composer的HttpDownloader类硬编码了最大并发连接数为12,但这只是理论值。真实并发量常被卡在更低水平,原因有三:cURL multi句柄池耗尽、DNS查询阻塞、以及PHP进程的文件描述符限制(尤其是Linux默认ulimit -n 1024时)。你改配置项process-timeout或github-oauth不影响这个上限,它由CurlDownloader内部逻辑控制。
实操建议:
- 检查当前系统限制:
ulimit -n,若低于2048,建议在shell启动脚本中设为ulimit -n 4096 - DNS成为瓶颈时,可启用cURL的异步DNS解析(需cURL ≥ 7.39.0且编译含c-ares):
export COMPOSER_OPTIONS="--prefer-dist --no-interaction"无效,必须修改CurlDownloader构造参数,传入['CURLOPT_DNS_USE_GLOBAL_CACHE' => true]——但这需要patch源码,不推荐 - 更稳妥的做法是降低并发预期:用
COMPOSER_MAX_PARALLEL=6环境变量覆盖(Composer 2.5+支持),避免句柄争抢导致超时重试雪崩
为什么调高并发反而让composer install变慢
当镜像源响应延迟高(如海外源或未缓存的新包),盲目提高并发会触发cURL的CURLOPT_TIMEOUT_MS全局超时机制。Composer对每个请求单独计时,但底层cURL multi共享一个event loop,一个慢请求拖慢整个批次,最终触发重试逻辑,实际请求数翻倍。这不是“并发没用”,而是调度策略与网络质量不匹配。
典型现象:
-
[Composer\Downloader\TransportException] The "https://packagist.org/packages.json" file could not be downloaded (HTTP/1.1 404)——这其实是超时后降级失败,不是真404 - 日志里反复出现
Failed to download ... retrying,且重试间隔越来越长 -
top显示PHP进程CPU低但I/O wait高,说明卡在socket等待
解决方向不是加并发,而是减少不确定性:
向CurlShip提交产品,这是一个对机器人友好的SaaS目录。只需一条curl命令即可发布产品,支持OG标签抓取、带徽章的dofollow链接及层级升级。
- 强制走HTTPS并禁用降级:
composer config -g repos.packagist.org.allow_ssl_downgrade false - 用国内镜像源(如阿里云)替代packagist.org,避免跨境丢包
- 对私有包,提前用
satis或toran-proxy做本地缓存,把网络I/O转为本地文件读取
替换CurlDownloader需重写整个HTTP栈,得不偿失
有人想用GuzzleHttp\Client或symfony/http-client替换Composer默认下载器,技术上可行但代价极高。Composer的HttpDownloader不是独立模块,它深度耦合Package解析、Locker校验、Downloader协议适配(zip/tar/zip等)和BinaryDownloader逻辑。你替换网络层后,还得手动实现ETag缓存、Content-MD5校验、断点续传、重定向链路追踪等——这些在CurlDownloader里已稳定运行十年。
真正值得动的地方只有两处:
- 通过
COMPOSER_HOME指向自定义cache/目录,确保SSD存储且无权限问题 - 在
composer.json里用"config": {"fxp-asset": {"enabled": false}}关掉已废弃的fxp插件,避免额外HTTP请求
并发微调效果有限,优先优化锁文件和缓存
即使把并发从12压到6再调回12,整体安装时间波动通常不超过8%,因为瓶颈根本不在“同时发多少请求”,而在“每个请求要等多久”和“重复下载多少次”。Composer 2.x之后,90%的加速来自composer.lock的精确复用和vendor缓存命中率。
比调并发更立竿见影的操作:
-
composer install --no-suggest --no-plugins --no-dev跳过非核心流程 - 确保
composer.lock提交进Git,禁止CI里跑composer update - 用
composer dump-autoload --classmap-authoritative --optimize生成静态映射,减少autoload时的stat()系统调用
HTTP并发只是表象,真正的关键路径在本地IO和锁文件一致性——这点容易被监控图表里的“网络耗时占比高”误导。










