Composer本身不支持自动就近切换,需镜像源配置、CDN智能调度(GSLB)和边缘缓存三者协同;DNS解析返回不同IP才表明GSLB生效,否则所有请求仍集中到同一中心节点。

Composer 本身不感知 DNS 调度,靠镜像源 + CDN + GSLB 协同生效
Composer 没有内置 DNS 地理调度能力,repo.packagist.org 配置项只认一个固定 URL,不会根据客户端位置自动切换域名或 IP。所谓“多机器拉取变快”,本质是让每台机器发出的请求被 DNS 解析到离它最近的边缘节点——这必须由镜像提供商在 CDN 层开启 GSLB(全局负载均衡),而非 Composer 自身行为。
常见错误是:配置了 https://mirrors.aliyun.com/composer/,但所有机器 dig mirrors.aliyun.com 都返回同一个北京 IP,说明 GSLB 未启用,流量根本没分散。
- 验证方式:在不同地区机器上分别执行
dig mirrors.aliyun.com,看是否返回不同 IP 段;再用curl -o /dev/null -s -w '%{time_starttransfer}\n' https://mirrors.aliyun.com/health测首字节延迟 - 必须确保镜像 URL 末尾带
/(如https://mirrors.tuna.tsinghua.edu.cn/composer/),否则 Composer 会拼出.../composer/packages.json这类错误路径 - 公司内网自建镜像时,若用私有域名(如
composer.internal),需在每台机器的/etc/resolv.conf或 DNS 服务器上配好 split-DNS,让该域名在不同机房解析到本地缓存节点
为什么 composer install 在多台机器上仍可能卡在 Resolving dependencies
这个阶段完全不走网络,但对 PHP 环境极其敏感。同一份 composer.lock 在不同机器上卡住,大概率不是 DNS 问题,而是:
-
memory_limit不足(尤其依赖树深时),建议临时设为COMPOSER_MEMORY_LIMIT=-1 - 某台机器启用了
xdebug(php -v可确认),会让依赖解析慢 5–10 倍;可用php -d xdebug.mode=off $(which composer) install绕过 - PHP 版本与
composer.json中platform.php不匹配,触发降级查找逻辑;例如锁定了"php": "8.1",但在 8.2 环境下运行,Composer 会反复回退尝试兼容版本 -
composer.lock含已下线包(如某私有包被删除),导致元数据探测失败后重试超时
http-max-concurrent-downloads 是唯一可控的并发下载参数
Composer 2.2+ 已弃用 parallel-downloads,改用 http-max-concurrent-downloads 控制 HTTP 并发连接数。它影响的是“同时发起多少个包的 ZIP 下载请求”,对多机器批量构建尤其关键:
- 默认值是 3,太保守;CI 环境建议设为
10:composer config -g http-max-concurrent-downloads 10 - 该值受 PHP 的
max_execution_time和系统文件描述符限制制约,设太高反而触发Too many open files - 配合
--prefer-dist使用效果更明显,避免 git clone 协议协商开销;但私有包若仅提供source类型,需在composer.json中单独配置"preferred-install": {"your-vendor/*": "source"}
CI 中不能依赖本地镜像配置,必须显式注入
GitHub Actions、GitLab CI 等环境默认无全局 Composer 配置,composer config -g 写入的只是当前 job 的临时 home 目录,下个 job 就失效。必须在每个构建步骤中显式设置:
- 先执行:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ - 再执行:
composer config -g http-max-concurrent-downloads 10 - 最后运行:
composer install --no-dev --prefer-dist --no-autoloader --no-scripts - 注意:Docker 构建中若用多阶段,
~/.composer缓存需通过COPY --from=builder /root/.composer/cache /root/.composer/cache显式传递,否则每次都是冷启动
/p2/ 路径没被 CDN 缓存(TTL 过短或 cache key 错误),每台机器仍会穿透回源。


















