Composer在CI中变慢主因是重复解析、串行下载与I/O瓶颈;应强制--prefer-dist、分层缓存~/.composer/cache、优化Docker构建顺序,并调优并发与DNS配置。

Composer 本身不参与负载调度——它没有调度器、不管理进程、也不分发请求。所谓“Composer 持续集成中的负载调度”,实际是误用术语,真正需要解决的是:在 CI 流程中高频执行 composer install 时,如何避免因重复解析、串行下载、I/O 瓶颈导致的构建排队、超时或资源争抢。
CI 中 composer install 变慢的典型现象
你在 GitLab CI / GitHub Actions 里看到这些表现,基本就踩进坑了:
-
composer install单次耗时超过 2 分钟,且随依赖数增长非线性上升 - 多个并行 job 同时拉取同一包(如
monolog/monolog),触发镜像源限流或带宽打满 - 缓存失效频繁:
vendor/每次重建,composer.lock微小变更就全量重装 - PHP 进程卡在
file_get_contents()或cURL等待网络响应,CPU 利用率长期低于 20%
用 --no-interaction 和 --prefer-dist 强制走二进制分发
默认情况下,Composer 在 CI 中可能回退到源码安装(--prefer-source),尤其当包作者未提供 dist 归档或校验失败时。这会显著放大磁盘 I/O 和解压开销。
必须显式指定:
composer install --no-interaction --prefer-dist --optimize-autoloader
-
--no-interaction:禁用任何交互提示,避免 CI 卡住 -
--prefer-dist:强制优先使用预编译的 zip/tar 包,跳过 git clone + checkout -
--optimize-autoloader:生成vendor/composer/autoload_classmap.php,省去运行时路径扫描
注意:--classmap-authoritative 在 CI 中慎用——它要求所有类必须出现在 classmap 中,一旦有动态加载(如插件机制、eval() 类文件),会导致 Class not found 错误。
利用 CI 缓存绕过重复下载与安装
关键不是缓存 vendor/ 目录本身(易受 PHP 版本、扩展差异影响),而是分层缓存更稳定的中间产物:
- 缓存
~/.composer/cache/:包含已下载的 dist 包、元数据 JSON、压缩包校验和,复用率最高 - 缓存
vendor/composer/installed.json+composer.lock的哈希组合:可作为vendor/缓存 key 的一部分 - 禁用
composer install --no-suggest:减少无关日志输出,加快终端渲染(尤其在低配 runner 上)
GitHub Actions 示例片段:
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}Docker 构建中避免重复 composer install
如果你在 CI 中用 docker build 打镜像,composer install 放在最后一步(如 COPY . /app && RUN composer install)会导致每次代码变更都失效整个 layer,白跑依赖安装。
正确顺序是:
- COPY
composer.json和composer.lock先 - RUN
composer install --no-dev --prefer-dist --optimize-autoloader - COPY 其余代码
这样只要 lock 文件不变,Docker 就能复用已安装依赖的 layer,构建提速 3–5 倍。别忘了在 Dockerfile 开头加 ARG COMPOSER_CACHE_DIR=/tmp/composer-cache 并挂载缓存卷,进一步加速。
最常被忽略的一点:CI runner 的磁盘 I/O 性能远低于本地 SSD,而 Composer 默认并发数(config.process-timeout)和 DNS 查询策略(config.dns-servers)几乎从不调整——这意味着你默认在用 1 核 + 机械硬盘 + 公网 DNS 跑本该并行的网络密集型任务。


















