composer不支持请求优先级调度,所有仓库请求按数组顺序线性尝试且共享12并发http下载器,priority字段无效,代理需同时配置http-proxy和https-proxy(后者协议必须为http://),故障转移依赖重试与仓库降级链而非动态调度。

Composer 本身不支持“请求优先级调度”——它没有按优先级抢占连接、插队重试或动态升降权的机制。所有仓库请求都走统一的 HTTP 下载器(HttpDownloader),并发数固定为 $maxJobs = 12,且任务排队是 FIFO(先进先出),不识别高优/低优语义。
为什么 composer config http-proxy + https-proxy 必须同时配对
Composer 对 HTTP 和 HTTPS 请求使用完全独立的代理路由逻辑:前者走 http-proxy 字段,后者必须走 https-proxy 字段才能建立 CONNECT 隧道。Packagist、GitHub 等全部依赖 HTTPS,漏掉 https-proxy 就等于让所有核心元数据请求 fallback 到直连,结果就是卡在 Loading composer repositories,无报错、无日志、只超时。
常见错误写法:
-
https-proxy值写成https://127.0.0.1:8080(协议错误,必须是http://) - 漏写协议头,如
127.0.0.1:8080 - 只配了全局
http-proxy,没配https-proxy
验证命令:composer config -g --list | grep -E "(http|https)-proxy",两行都存在且格式正确才算生效。
多仓库场景下,priority 字段实际无效
Composer 的 repositories 数组根本**不读取 priority 字段做权重调度**。它只按数组顺序线性尝试:第一个能返回有效包元数据的仓库就立即采用,后续全跳过。所谓“优先级”,其实是配置顺序的副作用,不是运行时调度策略。
这意味着:
-
"priority": 100和"priority": 50在行为上完全等价 - 私有包仓库必须放在第一位,否则同名包会被 packagist.org 先命中
- 镜像源要显式声明
"type": "packagist",否则会被当普通composer类型处理,索引能力残缺
真正影响“谁先被选中”的,只有 repositories 数组里的位置,不是字段值。
限流与失败转移靠的是重试 + fallback 链,不是优先级
Composer 的“故障转移”本质是单点重试 + 仓库降级链。当某个仓库在下载元数据或包文件时失败(如超时、503、404),它会按 repositories 数组顺序尝试下一个,直到成功或耗尽列表。
但这个过程没有速率限制、没有并发隔离、也没有优先保障:
- 所有仓库共享同一套
HttpDownloader并发池(最多 12 个并发) - 无法给私有仓分配更多连接数,也无法限制镜像仓的请求数
- 失败重试次数由
config.process-timeout和底层 cURL 设置隐式控制,不可按仓库粒度配置
如果你需要真正的流量分级,唯一可行路径是:把高优私有包单独拆到独立项目中,用 composer install --no-plugins --no-scripts 配合离线缓存 + --prefer-dist 强制走压缩包,绕过元数据实时查询。
最易被忽略的一点:Composer 的“优先级”全是静态配置层面的概念,运行时没有任何动态调度逻辑。你以为的 priority,只是你手写的 JSON 数组下标;你以为的限流,其实是靠网络层超时和重试兜底。真要压测或灰度发布,得在代理网关或 CDN 层做前置控制,别指望 Composer 自己扛。











